mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-01-19 03:09:30 +00:00
Merge pull request #60 from ceph/devel
Sync rhs/ceph-csi:devel with ceph/ceph-csi:devel
This commit is contained in:
commit
e5dc47c4b2
6
Makefile
6
Makefile
@ -200,9 +200,10 @@ containerized-test: .container-cmd .test-container-id
|
|||||||
|
|
||||||
ifeq ($(USE_PULLED_IMAGE),no)
|
ifeq ($(USE_PULLED_IMAGE),no)
|
||||||
# create a (cached) container image with dependencies for building cephcsi
|
# create a (cached) container image with dependencies for building cephcsi
|
||||||
|
.devel-container-id: GOARCH ?= $(shell go env GOARCH 2>/dev/null)
|
||||||
.devel-container-id: .container-cmd scripts/Dockerfile.devel
|
.devel-container-id: .container-cmd scripts/Dockerfile.devel
|
||||||
[ ! -f .devel-container-id ] || $(CONTAINER_CMD) rmi $(CSI_IMAGE_NAME):devel
|
[ ! -f .devel-container-id ] || $(CONTAINER_CMD) rmi $(CSI_IMAGE_NAME):devel
|
||||||
$(CONTAINER_CMD) build $(CPUSET) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t $(CSI_IMAGE_NAME):devel -f ./scripts/Dockerfile.devel .
|
$(CONTAINER_CMD) build $(CPUSET) --build-arg BASE_IMAGE=$(BASE_IMAGE) --build-arg GOARCH=$(GOARCH) -t $(CSI_IMAGE_NAME):devel -f ./scripts/Dockerfile.devel .
|
||||||
$(CONTAINER_CMD) inspect -f '{{.Id}}' $(CSI_IMAGE_NAME):devel > .devel-container-id
|
$(CONTAINER_CMD) inspect -f '{{.Id}}' $(CSI_IMAGE_NAME):devel > .devel-container-id
|
||||||
else
|
else
|
||||||
# create the .devel-container-id file based on pulled image
|
# create the .devel-container-id file based on pulled image
|
||||||
@ -211,10 +212,11 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_PULLED_IMAGE),no)
|
ifeq ($(USE_PULLED_IMAGE),no)
|
||||||
|
.test-container-id: GOARCH ?= $(shell go env GOARCH 2>/dev/null)
|
||||||
# create a (cached) container image with dependencies for testing cephcsi
|
# create a (cached) container image with dependencies for testing cephcsi
|
||||||
.test-container-id: .container-cmd build.env scripts/Dockerfile.test
|
.test-container-id: .container-cmd build.env scripts/Dockerfile.test
|
||||||
[ ! -f .test-container-id ] || $(CONTAINER_CMD) rmi $(CSI_IMAGE_NAME):test
|
[ ! -f .test-container-id ] || $(CONTAINER_CMD) rmi $(CSI_IMAGE_NAME):test
|
||||||
$(CONTAINER_CMD) build $(CPUSET) -t $(CSI_IMAGE_NAME):test -f ./scripts/Dockerfile.test .
|
$(CONTAINER_CMD) build $(CPUSET) --build-arg GOARCH=$(GOARCH) -t $(CSI_IMAGE_NAME):test -f ./scripts/Dockerfile.test .
|
||||||
$(CONTAINER_CMD) inspect -f '{{.Id}}' $(CSI_IMAGE_NAME):test > .test-container-id
|
$(CONTAINER_CMD) inspect -f '{{.Id}}' $(CSI_IMAGE_NAME):test > .test-container-id
|
||||||
else
|
else
|
||||||
# create the .test-container-id file based on the pulled image
|
# create the .test-container-id file based on the pulled image
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
module github.com/ceph/ceph-csi/actions/retest
|
module github.com/ceph/ceph-csi/actions/retest
|
||||||
|
|
||||||
go 1.16
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/go-github v17.0.0+incompatible
|
github.com/google/go-github v17.0.0+incompatible
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/golang/protobuf v1.4.2 // indirect
|
||||||
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect
|
||||||
|
google.golang.org/appengine v1.6.6 // indirect
|
||||||
|
google.golang.org/protobuf v1.25.0 // indirect
|
||||||
|
)
|
||||||
|
9
actions/retest/vendor/golang.org/x/oauth2/go.mod
generated
vendored
9
actions/retest/vendor/golang.org/x/oauth2/go.mod
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
module golang.org/x/oauth2
|
|
||||||
|
|
||||||
go 1.11
|
|
||||||
|
|
||||||
require (
|
|
||||||
cloud.google.com/go v0.65.0
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202
|
|
||||||
google.golang.org/appengine v1.6.6
|
|
||||||
)
|
|
361
actions/retest/vendor/golang.org/x/oauth2/go.sum
generated
vendored
361
actions/retest/vendor/golang.org/x/oauth2/go.sum
generated
vendored
@ -1,361 +0,0 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
|
||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
|
||||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
|
||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
|
||||||
cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
|
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
|
||||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
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/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
|
||||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
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/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
8
actions/retest/vendor/modules.txt
vendored
8
actions/retest/vendor/modules.txt
vendored
@ -1,19 +1,22 @@
|
|||||||
# github.com/golang/protobuf v1.4.2
|
# github.com/golang/protobuf v1.4.2
|
||||||
|
## explicit; go 1.9
|
||||||
github.com/golang/protobuf/proto
|
github.com/golang/protobuf/proto
|
||||||
# github.com/google/go-github v17.0.0+incompatible
|
# github.com/google/go-github v17.0.0+incompatible
|
||||||
## explicit
|
## explicit
|
||||||
github.com/google/go-github/github
|
github.com/google/go-github/github
|
||||||
# github.com/google/go-querystring v1.1.0
|
# github.com/google/go-querystring v1.1.0
|
||||||
## explicit
|
## explicit; go 1.10
|
||||||
github.com/google/go-querystring/query
|
github.com/google/go-querystring/query
|
||||||
# golang.org/x/net v0.0.0-20200822124328-c89045814202
|
# golang.org/x/net v0.0.0-20200822124328-c89045814202
|
||||||
|
## explicit; go 1.11
|
||||||
golang.org/x/net/context
|
golang.org/x/net/context
|
||||||
golang.org/x/net/context/ctxhttp
|
golang.org/x/net/context/ctxhttp
|
||||||
# golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
# golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||||
## explicit
|
## explicit; go 1.11
|
||||||
golang.org/x/oauth2
|
golang.org/x/oauth2
|
||||||
golang.org/x/oauth2/internal
|
golang.org/x/oauth2/internal
|
||||||
# google.golang.org/appengine v1.6.6
|
# google.golang.org/appengine v1.6.6
|
||||||
|
## explicit; go 1.11
|
||||||
google.golang.org/appengine/internal
|
google.golang.org/appengine/internal
|
||||||
google.golang.org/appengine/internal/base
|
google.golang.org/appengine/internal/base
|
||||||
google.golang.org/appengine/internal/datastore
|
google.golang.org/appengine/internal/datastore
|
||||||
@ -22,6 +25,7 @@ google.golang.org/appengine/internal/remote_api
|
|||||||
google.golang.org/appengine/internal/urlfetch
|
google.golang.org/appengine/internal/urlfetch
|
||||||
google.golang.org/appengine/urlfetch
|
google.golang.org/appengine/urlfetch
|
||||||
# google.golang.org/protobuf v1.25.0
|
# google.golang.org/protobuf v1.25.0
|
||||||
|
## explicit; go 1.9
|
||||||
google.golang.org/protobuf/encoding/prototext
|
google.golang.org/protobuf/encoding/prototext
|
||||||
google.golang.org/protobuf/encoding/protowire
|
google.golang.org/protobuf/encoding/protowire
|
||||||
google.golang.org/protobuf/internal/descfmt
|
google.golang.org/protobuf/internal/descfmt
|
||||||
|
@ -6,50 +6,49 @@ snapshot contents and then mount that volume to workloads.
|
|||||||
|
|
||||||
CephFS exposes snapshots as special, read-only directories of a subvolume
|
CephFS exposes snapshots as special, read-only directories of a subvolume
|
||||||
located in `<subvolume>/.snap`. cephfs-csi can already provision writable
|
located in `<subvolume>/.snap`. cephfs-csi can already provision writable
|
||||||
volumes with snapshots as their data source, where snapshot contents are
|
volumes with snapshots as their data source, where snapshot contents are cloned
|
||||||
cloned to the newly created volume. However, cloning a snapshot to volume
|
to the newly created volume. However, cloning a snapshot to volume is a very
|
||||||
is a very expensive operation in CephFS as the data needs to be fully copied.
|
expensive operation in CephFS as the data needs to be fully copied. When the
|
||||||
When the need is to only read snapshot contents, snapshot cloning is extremely
|
need is to only read snapshot contents, snapshot cloning is extremely
|
||||||
inefficient and wasteful.
|
inefficient and wasteful.
|
||||||
|
|
||||||
This proposal describes a way for cephfs-csi to expose CephFS snapshots
|
This proposal describes a way for cephfs-csi to expose CephFS snapshots as
|
||||||
as shallow, read-only volumes, without needing to clone the underlying
|
shallow, read-only volumes, without needing to clone the underlying snapshot
|
||||||
snapshot data.
|
data.
|
||||||
|
|
||||||
## Use-cases
|
## Use-cases
|
||||||
|
|
||||||
What's the point of such read-only volumes?
|
What's the point of such read-only volumes?
|
||||||
|
|
||||||
* **Restore snapshots selectively:** users may want to traverse snapshots,
|
* **Restore snapshots selectively:** users may want to traverse snapshots,
|
||||||
restoring data to a writable volume more selectively instead of restoring
|
restoring data to a writable volume more selectively instead of restoring the
|
||||||
the whole snapshot.
|
whole snapshot.
|
||||||
* **Volume backup:** users can't backup a live volume, they first need
|
* **Volume backup:** users can't backup a live volume, they first need to
|
||||||
to snapshot it. Once a snapshot is taken, it still can't be backed-up,
|
snapshot it. Once a snapshot is taken, it still can't be backed-up, as backup
|
||||||
as backup tools usually work with volumes (that are exposed as file-systems)
|
tools usually work with volumes (that are exposed as file-systems)
|
||||||
and not snapshots (which might have backend-specific format). What this means
|
and not snapshots (which might have backend-specific format). What this means
|
||||||
is that in order to create a snapshot backup, users have to clone snapshot
|
is that in order to create a snapshot backup, users have to clone snapshot
|
||||||
data twice:
|
data twice:
|
||||||
|
|
||||||
1. first time, when restoring the snapshot into a temporary volume from
|
1. first time, when restoring the snapshot into a temporary volume from
|
||||||
where the data will be read,
|
where the data will be read,
|
||||||
1. and second time, when transferring that volume into some backup/archive
|
1. and second time, when transferring that volume into some backup/archive
|
||||||
storage (e.g. object store).
|
storage (e.g. object store).
|
||||||
|
|
||||||
The temporary backed-up volume will most likely be thrown away after the
|
The temporary backed-up volume will most likely be thrown away after the
|
||||||
backup transfer is finished. That's a lot of wasted work for what we
|
backup transfer is finished. That's a lot of wasted work for what we
|
||||||
originally wanted to do! Having the ability to create volumes from
|
originally wanted to do! Having the ability to create volumes from snapshots
|
||||||
snapshots cheaply would be a big improvement for this use case.
|
cheaply would be a big improvement for this use case.
|
||||||
|
|
||||||
## Alternatives
|
## Alternatives
|
||||||
|
|
||||||
* _Snapshots are stored in `<subvolume>/.snap`. Users could simply visit this
|
* _Snapshots are stored in `<subvolume>/.snap`. Users could simply visit this
|
||||||
directory by themselves._
|
directory by themselves._
|
||||||
|
|
||||||
`.snap` is CephFS-specific detail of how snapshots are exposed.
|
`.snap` is CephFS-specific detail of how snapshots are exposed. Users / tools
|
||||||
Users / tools may not be aware of this special directory, or it may not fit
|
may not be aware of this special directory, or it may not fit their workflow.
|
||||||
their workflow. At the moment, the idiomatic way of accessing snapshot
|
At the moment, the idiomatic way of accessing snapshot contents in CSI drivers
|
||||||
contents in CSI drivers is by creating a new volume and populating it
|
is by creating a new volume and populating it with snapshot.
|
||||||
with snapshot.
|
|
||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
@ -57,21 +56,21 @@ Key points:
|
|||||||
|
|
||||||
* Volume source is a snapshot, volume access mode is `*_READER_ONLY`.
|
* Volume source is a snapshot, volume access mode is `*_READER_ONLY`.
|
||||||
* No actual new subvolumes are created in CephFS.
|
* No actual new subvolumes are created in CephFS.
|
||||||
* The resulting volume is a reference to the source subvolume snapshot.
|
* The resulting volume is a reference to the source subvolume snapshot. This
|
||||||
This reference would be stored in `Volume.volume_context` map. In order
|
reference would be stored in `Volume.volume_context` map. In order to
|
||||||
to reference a snapshot, we need subvol name and snapshot name.
|
reference a snapshot, we need subvol name and snapshot name.
|
||||||
* Mounting such volume means mounting the respective CephFS subvolume
|
* Mounting such volume means mounting the respective CephFS subvolume and
|
||||||
and exposing the snapshot to workloads.
|
exposing the snapshot to workloads.
|
||||||
* Let's call a *shallow read-only volume with a subvolume snapshot
|
* Let's call a *shallow read-only volume with a subvolume snapshot as its data
|
||||||
as its data source* just a *shallow volume* from here on out for brevity.
|
source* just a *shallow volume* from here on out for brevity.
|
||||||
|
|
||||||
### Controller operations
|
### Controller operations
|
||||||
|
|
||||||
Care must be taken when handling life-times of relevant storage resources.
|
Care must be taken when handling life-times of relevant storage resources. When
|
||||||
When a shallow volume is created, what would happen if:
|
a shallow volume is created, what would happen if:
|
||||||
|
|
||||||
* _Parent subvolume of the snapshot is removed while the shallow volume
|
* _Parent subvolume of the snapshot is removed while the shallow volume still
|
||||||
still exists?_
|
exists?_
|
||||||
|
|
||||||
This shouldn't be a problem already. The parent volume has either
|
This shouldn't be a problem already. The parent volume has either
|
||||||
`snapshot-retention` subvol feature in which case its snapshots remain
|
`snapshot-retention` subvol feature in which case its snapshots remain
|
||||||
@ -80,8 +79,8 @@ When a shallow volume is created, what would happen if:
|
|||||||
* _Source snapshot from which the shallow volume originates is removed while
|
* _Source snapshot from which the shallow volume originates is removed while
|
||||||
that shallow volume still exists?_
|
that shallow volume still exists?_
|
||||||
|
|
||||||
We need to make sure this doesn't happen and some book-keeping
|
We need to make sure this doesn't happen and some book-keeping is necessary.
|
||||||
is necessary. Ideally we could employ some kind of reference counting.
|
Ideally we could employ some kind of reference counting.
|
||||||
|
|
||||||
#### Reference counting for shallow volumes
|
#### Reference counting for shallow volumes
|
||||||
|
|
||||||
@ -92,26 +91,26 @@ When creating a volume snapshot, a reference tracker (RT), represented by a
|
|||||||
RADOS object, would be created for that snapshot. It would store information
|
RADOS object, would be created for that snapshot. It would store information
|
||||||
required to track the references for the backing subvolume snapshot. Upon a
|
required to track the references for the backing subvolume snapshot. Upon a
|
||||||
`CreateSnapshot` call, the reference tracker (RT) would be initialized with a
|
`CreateSnapshot` call, the reference tracker (RT) would be initialized with a
|
||||||
single reference record, where the CSI snapshot itself is the first reference
|
single reference record, where the CSI snapshot itself is the first reference to
|
||||||
to the backing snapshot. Each subsequent shallow volume creation would add a
|
the backing snapshot. Each subsequent shallow volume creation would add a new
|
||||||
new reference record to the RT object. Each shallow volume deletion would
|
reference record to the RT object. Each shallow volume deletion would remove
|
||||||
remove that reference from the RT object. Calling `DeleteSnapshot` would remove
|
that reference from the RT object. Calling `DeleteSnapshot` would remove the
|
||||||
the reference record that was previously added in `CreateSnapshot`.
|
reference record that was previously added in `CreateSnapshot`.
|
||||||
|
|
||||||
The subvolume snapshot would be removed from the Ceph cluster only once the RT
|
The subvolume snapshot would be removed from the Ceph cluster only once the RT
|
||||||
object holds no references. Note that this behavior would permit calling
|
object holds no references. Note that this behavior would permit calling
|
||||||
`DeleteSnapshot` even if it is still referenced by shallow volumes.
|
`DeleteSnapshot` even if it is still referenced by shallow volumes.
|
||||||
|
|
||||||
* `DeleteSnapshot`:
|
* `DeleteSnapshot`:
|
||||||
* RT holds no references or the RT object doesn't exist:
|
* RT holds no references or the RT object doesn't exist:
|
||||||
delete the backing snapshot too.
|
delete the backing snapshot too.
|
||||||
* RT holds at least one reference: keep the backing snapshot.
|
* RT holds at least one reference: keep the backing snapshot.
|
||||||
* `DeleteVolume`:
|
* `DeleteVolume`:
|
||||||
* RT holds no references: delete the backing snapshot too.
|
* RT holds no references: delete the backing snapshot too.
|
||||||
* RT holds at least one reference: keep the backing snapshot.
|
* RT holds at least one reference: keep the backing snapshot.
|
||||||
|
|
||||||
To enable creating shallow volumes from snapshots that were provisioned by
|
To enable creating shallow volumes from snapshots that were provisioned by older
|
||||||
older versions of cephfs-csi (i.e. before this feature is introduced),
|
versions of cephfs-csi (i.e. before this feature is introduced),
|
||||||
`CreateVolume` for shallow volumes would also create an RT object in case it's
|
`CreateVolume` for shallow volumes would also create an RT object in case it's
|
||||||
missing. It would be initialized to two: the source snapshot and the newly
|
missing. It would be initialized to two: the source snapshot and the newly
|
||||||
created shallow volume.
|
created shallow volume.
|
||||||
@ -141,17 +140,17 @@ Things to look out for:
|
|||||||
|
|
||||||
It doesn't consume any space on the filesystem. `Volume.capacity_bytes` is
|
It doesn't consume any space on the filesystem. `Volume.capacity_bytes` is
|
||||||
allowed to contain zero. We could use that.
|
allowed to contain zero. We could use that.
|
||||||
* _What should be the requested size when creating the volume (specified e.g.
|
* _What should be the requested size when creating the volume (specified e.g. in
|
||||||
in PVC)?_
|
PVC)?_
|
||||||
|
|
||||||
This one is tricky. CSI spec allows for
|
This one is tricky. CSI spec allows for
|
||||||
`CreateVolumeRequest.capacity_range.{required_bytes,limit_bytes}` to be
|
`CreateVolumeRequest.capacity_range.{required_bytes,limit_bytes}` to be zero.
|
||||||
zero. On the other hand,
|
On the other hand,
|
||||||
`PersistentVolumeClaim.spec.resources.requests.storage` must be bigger
|
`PersistentVolumeClaim.spec.resources.requests.storage` must be bigger than
|
||||||
than zero. cephfs-csi doesn't care about the requested size (the volume
|
zero. cephfs-csi doesn't care about the requested size (the volume will be
|
||||||
will be read-only, so it has no usable capacity) and would always set it
|
read-only, so it has no usable capacity) and would always set it to zero. This
|
||||||
to zero. This shouldn't case any problems for the time being, but still
|
shouldn't case any problems for the time being, but still is something we
|
||||||
is something we should keep in mind.
|
should keep in mind.
|
||||||
|
|
||||||
`CreateVolume` and behavior when using volume as volume source (PVC-PVC clone):
|
`CreateVolume` and behavior when using volume as volume source (PVC-PVC clone):
|
||||||
|
|
||||||
@ -167,8 +166,8 @@ Volume deletion is trivial.
|
|||||||
|
|
||||||
### `CreateSnapshot`
|
### `CreateSnapshot`
|
||||||
|
|
||||||
Snapshotting read-only volumes doesn't make sense in general, and should
|
Snapshotting read-only volumes doesn't make sense in general, and should be
|
||||||
be rejected.
|
rejected.
|
||||||
|
|
||||||
### `ControllerExpandVolume`
|
### `ControllerExpandVolume`
|
||||||
|
|
||||||
@ -194,8 +193,8 @@ whole subvolume first, and only then perform the binds to target paths.
|
|||||||
#### For case (a)
|
#### For case (a)
|
||||||
|
|
||||||
Subvolume paths are normally retrieved by
|
Subvolume paths are normally retrieved by
|
||||||
`ceph fs subvolume info/getpath <VOLUME NAME> <SUBVOLUME NAME> <SUBVOLUMEGROUP NAME>`,
|
`ceph fs subvolume info/getpath <VOLUME NAME> <SUBVOLUME NAME> <SUBVOLUMEGROUP NAME>`
|
||||||
which outputs a path like so:
|
, which outputs a path like so:
|
||||||
|
|
||||||
```
|
```
|
||||||
/volumes/<VOLUME NAME>/<SUBVOLUME NAME>/<UUID>
|
/volumes/<VOLUME NAME>/<SUBVOLUME NAME>/<UUID>
|
||||||
@ -217,12 +216,12 @@ itself still exists or not.
|
|||||||
|
|
||||||
#### For case (b)
|
#### For case (b)
|
||||||
|
|
||||||
For cases where subvolumes are managed externally and not by cephfs-csi, we
|
For cases where subvolumes are managed externally and not by cephfs-csi, we must
|
||||||
must assume that the cephx user we're given can access only
|
assume that the cephx user we're given can access only
|
||||||
`/volumes/<VOLUME NAME>/<SUBVOLUME NAME>/<UUID>` so users won't be able to
|
`/volumes/<VOLUME NAME>/<SUBVOLUME NAME>/<UUID>` so users won't be able to
|
||||||
benefit from snapshot retention. Users will need to be careful not to delete
|
benefit from snapshot retention. Users will need to be careful not to delete the
|
||||||
the parent subvolumes and snapshots while they are associated by these shallow
|
parent subvolumes and snapshots while they are associated by these shallow RO
|
||||||
RO volumes.
|
volumes.
|
||||||
|
|
||||||
### `NodePublishVolume`, `NodeUnpublishVolume`
|
### `NodePublishVolume`, `NodeUnpublishVolume`
|
||||||
|
|
||||||
@ -235,38 +234,38 @@ mount.
|
|||||||
|
|
||||||
## Volume parameters, volume context
|
## Volume parameters, volume context
|
||||||
|
|
||||||
This section provides a discussion around determinig what volume parameters and
|
This section provides a discussion around determining what volume parameters and
|
||||||
volume context parameters will be used to convey necessary information to the
|
volume context parameters will be used to convey necessary information to the
|
||||||
cephfs-csi driver in order to support shallow volumes.
|
cephfs-csi driver in order to support shallow volumes.
|
||||||
|
|
||||||
Volume parameters `CreateVolumeRequest.parameters`:
|
Volume parameters `CreateVolumeRequest.parameters`:
|
||||||
|
|
||||||
* Should be "shallow" the default mode for all `CreateVolume` calls that have
|
* Should be "shallow" the default mode for all `CreateVolume` calls that have
|
||||||
(a) snapshot as data source and (b) read-only volume access mode? If not,
|
(a) snapshot as data source and (b) read-only volume access mode? If not, a
|
||||||
a new volume parameter should be introduced: e.g `isShallow: <bool>`. On the
|
new volume parameter should be introduced: e.g `isShallow: <bool>`. On the
|
||||||
other hand, does it even makes sense for users to want to create full copies
|
other hand, does it even makes sense for users to want to create full copies
|
||||||
of snapshots and still have them read-only?
|
of snapshots and still have them read-only?
|
||||||
|
|
||||||
Volume context `Volume.volume_context`:
|
Volume context `Volume.volume_context`:
|
||||||
|
|
||||||
* Here we definitely need `isShallow` or similar. Without it we wouldn't be
|
* Here we definitely need `isShallow` or similar. Without it we wouldn't be able
|
||||||
able to distinguish between a regular volume that just happens to have
|
to distinguish between a regular volume that just happens to have a read-only
|
||||||
a read-only access mode, and a volume that references a snapshot.
|
access mode, and a volume that references a snapshot.
|
||||||
* Currently cephfs-csi recognizes `subvolumePath` for dynamically provisioned
|
* Currently cephfs-csi recognizes `subvolumePath` for dynamically provisioned
|
||||||
volumes and `rootPath` for pre-previsioned volumes. As mentioned in
|
volumes and `rootPath` for pre-previsioned volumes. As mentioned in
|
||||||
[`NodeStageVolume`, `NodeUnstageVolume` section](#NodeStageVolume-NodeUnstageVolume),
|
[`NodeStageVolume`, `NodeUnstageVolume` section](#NodeStageVolume-NodeUnstageVolume)
|
||||||
snapshots cannot be mounted directly. How do we pass in path to the parent
|
, snapshots cannot be mounted directly. How do we pass in path to the parent
|
||||||
subvolume?
|
subvolume?
|
||||||
* a) Path to the snapshot is passed in via `subvolumePath` / `rootPath`,
|
* a) Path to the snapshot is passed in via `subvolumePath` / `rootPath`,
|
||||||
e.g.
|
e.g.
|
||||||
`/volumes/<VOLUME NAME>/<SUBVOLUME NAME>/<UUID>/.snap/<SNAPSHOT NAME>`.
|
`/volumes/<VOLUME NAME>/<SUBVOLUME NAME>/<UUID>/.snap/<SNAPSHOT NAME>`.
|
||||||
From that we can derive path to the subvolume: it's the parent of `.snap`
|
From that we can derive path to the subvolume: it's the parent of `.snap`
|
||||||
directory.
|
directory.
|
||||||
* b) Similar to a), path to the snapshot is passed in via `subvolumePath` /
|
* b) Similar to a), path to the snapshot is passed in via `subvolumePath` /
|
||||||
`rootPath`, but instead of trying to derive the right path we introduce
|
`rootPath`, but instead of trying to derive the right path we introduce
|
||||||
another volume context parameter containing path to the parent subvolume
|
another volume context parameter containing path to the parent subvolume
|
||||||
explicitly.
|
explicitly.
|
||||||
* c) `subvolumePath` / `rootPath` contains path to the parent subvolume and
|
* c) `subvolumePath` / `rootPath` contains path to the parent subvolume and
|
||||||
we introduce another volume context parameter containing name of the
|
we introduce another volume context parameter containing name of the
|
||||||
snapshot. Path to the snapshot is then formed by appending
|
snapshot. Path to the snapshot is then formed by appending
|
||||||
`/.snap/<SNAPSHOT NAME>` to the subvolume path.
|
`/.snap/<SNAPSHOT NAME>` to the subvolume path.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Design to handle clusterID and poolID for DR
|
# Design to handle clusterID and poolID for DR
|
||||||
|
|
||||||
During disaster recovery/migration of a cluster, as part of the failover, the
|
During disaster recovery/migration of a cluster, as part of the failover, the
|
||||||
kubernetes artifacts like deployment, PVC, PV, etc will be restored to a new
|
kubernetes artifacts like deployment, PVC, PV, etc. will be restored to a new
|
||||||
cluster by the admin. Even if the kubernetes objects are restored the
|
cluster by the admin. Even if the kubernetes objects are restored the
|
||||||
corresponding RBD/CephFS subvolume cannot be retrieved during CSI operations as
|
corresponding RBD/CephFS subvolume cannot be retrieved during CSI operations as
|
||||||
the clusterID and poolID are not the same in both clusters. Let's see the
|
the clusterID and poolID are not the same in both clusters. Let's see the
|
||||||
@ -10,8 +10,8 @@ problem in more detail below.
|
|||||||
`0001-0009-rook-ceph-0000000000000002-b0285c97-a0ce-11eb-8c66-0242ac110002`
|
`0001-0009-rook-ceph-0000000000000002-b0285c97-a0ce-11eb-8c66-0242ac110002`
|
||||||
|
|
||||||
The above is the sample volumeID sent back in response to the CreateVolume
|
The above is the sample volumeID sent back in response to the CreateVolume
|
||||||
operation and added as a volumeHandle in the PV spec. CO (Kubernetes) uses
|
operation and added as a volumeHandle in the PV spec. CO (Kubernetes) uses above
|
||||||
above as the identifier for other operations on the volume/PVC.
|
as the identifier for other operations on the volume/PVC.
|
||||||
|
|
||||||
The VolumeID is encoded as,
|
The VolumeID is encoded as,
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ the other cluster.
|
|||||||
|
|
||||||
During the Disaster Recovery (failover operation) the PVC and PV will be
|
During the Disaster Recovery (failover operation) the PVC and PV will be
|
||||||
recreated on the other cluster. When Ceph-CSI receives the request for
|
recreated on the other cluster. When Ceph-CSI receives the request for
|
||||||
operations like (NodeStage, ExpandVolume, DeleteVolume, etc) the volumeID is
|
operations like (NodeStage, ExpandVolume, DeleteVolume, etc.) the volumeID is
|
||||||
sent in the request which will help to identify the volume.
|
sent in the request which will help to identify the volume.
|
||||||
|
|
||||||
```yaml=
|
```yaml=
|
||||||
@ -68,15 +68,15 @@ metadata:
|
|||||||
```
|
```
|
||||||
|
|
||||||
During CSI/Replication operations, Ceph-CSI will decode the volumeID and gets
|
During CSI/Replication operations, Ceph-CSI will decode the volumeID and gets
|
||||||
the monitor configuration from the configmap and by the poolID will get the
|
the monitor configuration from the configmap and by the poolID will get the pool
|
||||||
pool Name and retrieves the OMAP data stored in the rados OMAP and finally
|
Name and retrieves the OMAP data stored in the rados OMAP and finally check the
|
||||||
check the volume is present in the pool.
|
volume is present in the pool.
|
||||||
|
|
||||||
## Problems with volumeID Replication
|
## Problems with volumeID Replication
|
||||||
|
|
||||||
* The clusterID can be different
|
* The clusterID can be different
|
||||||
* as the clusterID is the namespace where rook is deployed, the Rook might be
|
* as the clusterID is the namespace where rook is deployed, the Rook might
|
||||||
deployed in the different namespace on a secondary cluster
|
be deployed in the different namespace on a secondary cluster
|
||||||
* In standalone Ceph-CSI the clusterID is fsID and fsID is unique per
|
* In standalone Ceph-CSI the clusterID is fsID and fsID is unique per
|
||||||
cluster
|
cluster
|
||||||
|
|
||||||
@ -124,8 +124,8 @@ metadata:
|
|||||||
name: ceph-csi-config
|
name: ceph-csi-config
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:-** the configmap will be mounted as a volume to the CSI (provisioner
|
**Note:-** the configmap will be mounted as a volume to the CSI (provisioner and
|
||||||
and node plugin) pods.
|
node plugin) pods.
|
||||||
|
|
||||||
The above configmap will get created as it is or updated (if new Pools are
|
The above configmap will get created as it is or updated (if new Pools are
|
||||||
created on the existing cluster) with new entries when the admin choose to
|
created on the existing cluster) with new entries when the admin choose to
|
||||||
@ -149,28 +149,28 @@ Replicapool with ID `1` on site1 and Replicapool with ID `2` on site2.
|
|||||||
After getting the required mapping Ceph-CSI has the required information to get
|
After getting the required mapping Ceph-CSI has the required information to get
|
||||||
more details from the rados OMAP. If we have multiple clusterID mapping it will
|
more details from the rados OMAP. If we have multiple clusterID mapping it will
|
||||||
loop through all the mapping and checks the corresponding pool to get the OMAP
|
loop through all the mapping and checks the corresponding pool to get the OMAP
|
||||||
data. If the clusterID mapping does not exist Ceph-CSI will return a `Not
|
data. If the clusterID mapping does not exist Ceph-CSI will return a `Not Found`
|
||||||
Found` error message to the caller.
|
error message to the caller.
|
||||||
|
|
||||||
After failover to the cluster `site2-storage`, the admin might have created new
|
After failover to the cluster `site2-storage`, the admin might have created new
|
||||||
PVCs on the primary cluster `site2-storage`. Later after recovering the
|
PVCs on the primary cluster `site2-storage`. Later after recovering the
|
||||||
cluster `site1-storage`, the admin might choose to failback from
|
cluster `site1-storage`, the admin might choose to failback from
|
||||||
`site2-storage` to `site1-storage`. Now admin needs to copy all the newly
|
`site2-storage` to `site1-storage`. Now admin needs to copy all the newly
|
||||||
created kubernetes artifacts to the failback cluster. For clusterID mapping, the
|
created kubernetes artifacts to the failback cluster. For clusterID mapping, the
|
||||||
admin needs to copy the above-created configmap `ceph-clusterid-mapping` to
|
admin needs to copy the above-created configmap `ceph-clusterid-mapping` to the
|
||||||
the failback cluster. When Ceph-CSI receives a CSI/Replication request for
|
failback cluster. When Ceph-CSI receives a CSI/Replication request for the
|
||||||
the volumes created on the `site2-storage` it will decode the volumeID and
|
volumes created on the `site2-storage` it will decode the volumeID and retrieves
|
||||||
retrieves the clusterID ie `site2-storage`. In the above configmap
|
the clusterID ie `site2-storage`. In the above configmap
|
||||||
`ceph-clusterid-mapping` the `site2-storage` is the value and `site1-storage`
|
`ceph-clusterid-mapping` the `site2-storage` is the value and `site1-storage`
|
||||||
is the key in the `clusterIDMapping` entry.
|
is the key in the `clusterIDMapping` entry.
|
||||||
|
|
||||||
Ceph-CSI will check both `key` and `value` to check the clusterID mapping. If it
|
Ceph-CSI will check both `key` and `value` to check the clusterID mapping. If it
|
||||||
is found in `key` it will consider `value` as the corresponding mapping, if it
|
is found in `key` it will consider `value` as the corresponding mapping, if it
|
||||||
is found in `value` place it will treat `key` as the corresponding mapping and
|
is found in `value` place it will treat `key` as the corresponding mapping and
|
||||||
retrieves all the poolID details of the cluster.
|
retrieves all the poolID details of the cluster.
|
||||||
|
|
||||||
This mapping on the remote cluster is only required when we are doing a
|
This mapping on the remote cluster is only required when we are doing a failover
|
||||||
failover operation from the primary cluster to a remote cluster. The existing
|
operation from the primary cluster to a remote cluster. The existing volumes
|
||||||
volumes that are created on the remote cluster does not require
|
that are created on the remote cluster does not require any mapping as the
|
||||||
any mapping as the volumeHandle already contains the required information about
|
volumeHandle already contains the required information about the local cluster (
|
||||||
the local cluster (clusterID, poolID etc).
|
clusterID, poolID etc).
|
||||||
|
68
docs/design/proposals/encryped-with-keyprotect.md
Normal file
68
docs/design/proposals/encryped-with-keyprotect.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# Encrypted volumes with IBM HPCS or Key Protect
|
||||||
|
|
||||||
|
IBM Cloud™ Hyper Protect Crypto Services is a key management and cloud hardware
|
||||||
|
security module (HSM). It is designed to enable a user to take control of their
|
||||||
|
cloud data encryption keys and cloud hardware security models. To support this
|
||||||
|
KMS integration in Ceph CSI and thus enable the HPCS users to make use of the
|
||||||
|
same in volume encrypted operations, below things are considered.
|
||||||
|
|
||||||
|
## Connection to IBM HPCS/Key Protect service
|
||||||
|
|
||||||
|
Below parameters/values can be used to establish the connection to the HPCS
|
||||||
|
service from the CSI driver and to make use of the encryption operations:
|
||||||
|
|
||||||
|
```text
|
||||||
|
* KMS_SERVICE_NAME=[kms_service_name]
|
||||||
|
A unique name for the key management service within the project.
|
||||||
|
|
||||||
|
* KP_SERVICE_INSTANCE_ID=[service_instance_id]
|
||||||
|
The Instance ID of the IBM HPCS service, ex: crn:v1:bluemix:public:hs-crypto:us-south:a/5d19cf8b82874c2dab37e397426fbc42:e2ae65ff-954b-453f-b0d7-fc5064c203ce::
|
||||||
|
|
||||||
|
* KP_SERVICE_API_KEY=[service_api_key]
|
||||||
|
Ex: 06x6DbTkVQ-qCRmq9cK-p9xOQpU2UwJMcdjnIDdr0g2R
|
||||||
|
|
||||||
|
* KP_CUSTOMER_ROOT_KEY=[customer_root_key]
|
||||||
|
Ex: c7a9aa91-5cb5-48da-a821-e85c27b99d92
|
||||||
|
|
||||||
|
* KP_REGION = [region of the key protect service]
|
||||||
|
Ex: us-south-2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Values provided in the connection Secret
|
||||||
|
|
||||||
|
Considering `SERVICE_API_KEY` and `CUSTOMER_ROOT_KEY` are sensitive information,
|
||||||
|
those will be provided as a Kubernetes Secret to the CSI driver. The Ceph CSI
|
||||||
|
KMS plugin interface for the key protect will read the Secret name from the kms
|
||||||
|
ConfigMap and fetch these values. `SESSION_TOKEN and CRK_ARN` values can also be
|
||||||
|
provided by the user as part of the Secret if needed. How-ever these values are
|
||||||
|
considered to be optional.
|
||||||
|
|
||||||
|
### Values provided in the config map
|
||||||
|
|
||||||
|
`SERVICE_INSTANCE_ID` is part of the KMS ConfigMap and there could be an
|
||||||
|
optional value provided in the ConfigMap for `REGION` too.
|
||||||
|
|
||||||
|
### Storage class values or configuration
|
||||||
|
|
||||||
|
As like other KMS enablement, the Storage class has to be enabled for encryption
|
||||||
|
and `encryptionKMSID` has to be provided which is the matching value in the kms
|
||||||
|
config map to `KMS_SERVICE_NAME`.
|
||||||
|
|
||||||
|
## Volume Encrypt or Decrypt Operation
|
||||||
|
|
||||||
|
The IBM Key protect server's `wrap` and `unwrap` functionalities will be used by
|
||||||
|
the Ceph CSI driver to achieve encryption and decryption of volumes. The DEK can
|
||||||
|
be wrapped with the help of Customer Root Key (CRK) and can be used for LUKS
|
||||||
|
operation. The wrapped cipher blob will be stored inside the image metadata ( as
|
||||||
|
in other KMS integration, ex: AWS). At time of decrypt the DEK will be unwrapped
|
||||||
|
with the help of cipher blob and Key Protect server
|
||||||
|
|
||||||
|
## Integration APIS
|
||||||
|
|
||||||
|
[Key Protect Go Client](https://github.com/IBM/keyprotect-go-client) provide the
|
||||||
|
client SDK to interact with the Key Protect server and perform key protect
|
||||||
|
operations.
|
||||||
|
|
||||||
|
## Additional Reference
|
||||||
|
|
||||||
|
[Key Protect Doc](https://cloud.ibm.com/docs/key-protect)
|
@ -16,7 +16,7 @@ Some but not all the benefits of this approach:
|
|||||||
|
|
||||||
* volume encryption: encryption of a volume attached by rbd
|
* volume encryption: encryption of a volume attached by rbd
|
||||||
* encryption at rest: encryption of physical disk done by ceph
|
* encryption at rest: encryption of physical disk done by ceph
|
||||||
* LUKS: Linux Unified Key Setup: stores all of the needed setup information for
|
* LUKS: Linux Unified Key Setup: stores all the needed setup information for
|
||||||
dm-crypt on the disk
|
dm-crypt on the disk
|
||||||
* dm-crypt: linux kernel device-mapper crypto target
|
* dm-crypt: linux kernel device-mapper crypto target
|
||||||
* cryptsetup: the command line tool to interface with dm-crypt
|
* cryptsetup: the command line tool to interface with dm-crypt
|
||||||
@ -28,8 +28,8 @@ requirement by using dm-crypt module through cryptsetup cli interface.
|
|||||||
|
|
||||||
### Implementation Summary
|
### Implementation Summary
|
||||||
|
|
||||||
* Encryption is implemented using cryptsetup with LUKS extension.
|
* Encryption is implemented using cryptsetup with LUKS extension. A good
|
||||||
A good introduction to LUKS and dm-crypt in general can be found
|
introduction to LUKS and dm-crypt in general can be found
|
||||||
[here](https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption#Encrypting_devices_with_cryptsetup)
|
[here](https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption#Encrypting_devices_with_cryptsetup)
|
||||||
Functions to implement necessary interaction are implemented in a separate
|
Functions to implement necessary interaction are implemented in a separate
|
||||||
`cryptsetup.go` file.
|
`cryptsetup.go` file.
|
||||||
@ -45,8 +45,8 @@ requirement by using dm-crypt module through cryptsetup cli interface.
|
|||||||
volume attach request
|
volume attach request
|
||||||
* `NodeStageVolume`: refactored to open encrypted device (`openEncryptedDevice`)
|
* `NodeStageVolume`: refactored to open encrypted device (`openEncryptedDevice`)
|
||||||
* `openEncryptedDevice`: looks up for a passphrase matching the volume id,
|
* `openEncryptedDevice`: looks up for a passphrase matching the volume id,
|
||||||
returns the new device path in the form: `/dev/mapper/luks-<volume_id>`.
|
returns the new device path in the form: `/dev/mapper/luks-<volume_id>`. On
|
||||||
On the woker node where the attach is scheduled:
|
the worker node where the attach is scheduled:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ lsblk
|
$ lsblk
|
||||||
@ -62,10 +62,10 @@ requirement by using dm-crypt module through cryptsetup cli interface.
|
|||||||
before detaching the volume.
|
before detaching the volume.
|
||||||
|
|
||||||
* StorageClass extended with following parameters:
|
* StorageClass extended with following parameters:
|
||||||
1. `encrypted` ("true" or "false")
|
1. `encrypted` ("true" or "false")
|
||||||
1. `encryptionKMSID` (string representing kms configuration of choice)
|
2. `encryptionKMSID` (string representing kms configuration of choice)
|
||||||
ceph-csi plugin may support different kms vendors with different type of
|
ceph-csi plugin may support different kms vendors with different type of
|
||||||
authentication
|
authentication
|
||||||
|
|
||||||
* New KMS Configuration created.
|
* New KMS Configuration created.
|
||||||
|
|
||||||
@ -75,37 +75,37 @@ requirement by using dm-crypt module through cryptsetup cli interface.
|
|||||||
apiVersion: storage.k8s.io/v1
|
apiVersion: storage.k8s.io/v1
|
||||||
kind: StorageClass
|
kind: StorageClass
|
||||||
metadata:
|
metadata:
|
||||||
name: csi-rbd
|
name: csi-rbd
|
||||||
provisioner: rbd.csi.ceph.com
|
provisioner: rbd.csi.ceph.com
|
||||||
parameters:
|
parameters:
|
||||||
# String representing Ceph cluster configuration
|
# String representing Ceph cluster configuration
|
||||||
clusterID: <cluster-id>
|
clusterID: <cluster-id>
|
||||||
# ceph pool
|
# ceph pool
|
||||||
pool: rbd
|
pool: rbd
|
||||||
|
|
||||||
# RBD image features, CSI creates image with image-format 2
|
# RBD image features, CSI creates image with image-format 2
|
||||||
# CSI RBD currently supports only `layering` feature.
|
# CSI RBD currently supports only `layering` feature.
|
||||||
imageFeatures: layering
|
imageFeatures: layering
|
||||||
|
|
||||||
# The secrets have to contain Ceph credentials with required access
|
# The secrets have to contain Ceph credentials with required access
|
||||||
# to the 'pool'.
|
# to the 'pool'.
|
||||||
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
|
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
|
||||||
csi.storage.k8s.io/provisioner-secret-namespace: default
|
csi.storage.k8s.io/provisioner-secret-namespace: default
|
||||||
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
|
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
|
||||||
csi.storage.k8s.io/controller-expand-secret-namespace: default
|
csi.storage.k8s.io/controller-expand-secret-namespace: default
|
||||||
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
|
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
|
||||||
csi.storage.k8s.io/node-stage-secret-namespace: default
|
csi.storage.k8s.io/node-stage-secret-namespace: default
|
||||||
# Specify the filesystem type of the volume. If not specified,
|
# Specify the filesystem type of the volume. If not specified,
|
||||||
# csi-provisioner will set default as `ext4`.
|
# csi-provisioner will set default as `ext4`.
|
||||||
csi.storage.k8s.io/fstype: ext4
|
csi.storage.k8s.io/fstype: ext4
|
||||||
|
|
||||||
# Encrypt volumes
|
# Encrypt volumes
|
||||||
encrypted: "true"
|
encrypted: "true"
|
||||||
|
|
||||||
# Use external key management system for encryption passphrases by specifying
|
# Use external key management system for encryption passphrases by specifying
|
||||||
# a unique ID matching KMS ConfigMap. The ID is only used for correlation to
|
# a unique ID matching KMS ConfigMap. The ID is only used for correlation to
|
||||||
# configmap entry.
|
# configmap entry.
|
||||||
encryptionKMSID: <kms-id>
|
encryptionKMSID: <kms-id>
|
||||||
|
|
||||||
reclaimPolicy: Delete
|
reclaimPolicy: Delete
|
||||||
```
|
```
|
||||||
@ -133,14 +133,19 @@ metadata:
|
|||||||
The main components that are used to support encrypted volumes:
|
The main components that are used to support encrypted volumes:
|
||||||
|
|
||||||
1. the `EncryptionKMS` interface
|
1. the `EncryptionKMS` interface
|
||||||
* an instance is configured per volume object (`rbdVolume.KMS`)
|
|
||||||
* used to authenticate with a master key or token
|
* an instance is configured per volume object (`rbdVolume.KMS`)
|
||||||
* can store the KEK (Key-Encryption-Key) for encrypting and decrypting the
|
* used to authenticate with a master key or token
|
||||||
DEKs (Data-Encryption-Key)
|
* can store the KEK (Key-Encryption-Key) for encrypting and decrypting the
|
||||||
|
DEKs (Data-Encryption-Key)
|
||||||
|
|
||||||
1. the `DEKStore` interface
|
1. the `DEKStore` interface
|
||||||
* saves and fetches the DEK (Data-Encryption-Key)
|
|
||||||
* can be provided by a KMS, or by other components (like `rbdVolume`)
|
* saves and fetches the DEK (Data-Encryption-Key)
|
||||||
|
* can be provided by a KMS, or by other components (like `rbdVolume`)
|
||||||
|
|
||||||
1. the `VolumeEncryption` type
|
1. the `VolumeEncryption` type
|
||||||
* combines `EncryptionKMS` and `DEKStore` into a single place
|
|
||||||
* easy to configure from other components or subsystems
|
* combines `EncryptionKMS` and `DEKStore` into a single place
|
||||||
* provides a simple API for all KMS operations
|
* easy to configure from other components or subsystems
|
||||||
|
* provides a simple API for all KMS operations
|
||||||
|
@ -14,7 +14,8 @@ KMS implementation. Or, if changes would be minimal, a configuration option to
|
|||||||
one of the implementations can be added.
|
one of the implementations can be added.
|
||||||
|
|
||||||
Different KMS implementations and their configurable options can be found at
|
Different KMS implementations and their configurable options can be found at
|
||||||
[`csi-kms-connection-details.yaml`](../../../examples/kms/vault/csi-kms-connection-details.yaml).
|
[`csi-kms-connection-details.yaml`](../../../examples/kms/vault/csi-kms-connection-details.yaml)
|
||||||
|
.
|
||||||
|
|
||||||
### VaultTokensKMS
|
### VaultTokensKMS
|
||||||
|
|
||||||
@ -26,7 +27,8 @@ An example of the per Tenant configuration options are in
|
|||||||
[`tenant-config.yaml`](../../../examples/kms/vault/tenant-config.yaml) and
|
[`tenant-config.yaml`](../../../examples/kms/vault/tenant-config.yaml) and
|
||||||
[`tenant-token.yaml`](../../../examples/kms/vault/tenant-token.yaml).
|
[`tenant-token.yaml`](../../../examples/kms/vault/tenant-token.yaml).
|
||||||
|
|
||||||
Implementation is in [`vault_tokens.go`](../../../internal/util/vault_tokens.go).
|
Implementation is in [`vault_tokens.go`](../../../internal/util/vault_tokens.go)
|
||||||
|
.
|
||||||
|
|
||||||
### Vault
|
### Vault
|
||||||
|
|
||||||
@ -36,7 +38,7 @@ Implementation is in [`vault.go`](../../../internal/util/vault.go).
|
|||||||
|
|
||||||
## Extension or New KMS implementation
|
## Extension or New KMS implementation
|
||||||
|
|
||||||
Normally ServiceAccounts are provided by Kubernetes in the containers
|
Normally ServiceAccounts are provided by Kubernetes in the containers'
|
||||||
filesystem. This only allows a single ServiceAccount and is static for the
|
filesystem. This only allows a single ServiceAccount and is static for the
|
||||||
lifetime of the Pod. Ceph-CSI runs in the namespace of the storage
|
lifetime of the Pod. Ceph-CSI runs in the namespace of the storage
|
||||||
administrator, and has access to the single ServiceAccount linked in the
|
administrator, and has access to the single ServiceAccount linked in the
|
||||||
@ -53,7 +55,7 @@ steps need to be taken:
|
|||||||
replace the default (`AuthKubernetesTokenPath:
|
replace the default (`AuthKubernetesTokenPath:
|
||||||
/var/run/secrets/kubernetes.io/serviceaccount/token`)
|
/var/run/secrets/kubernetes.io/serviceaccount/token`)
|
||||||
|
|
||||||
Currently the Ceph-CSI components may read Secrets and ConfigMaps from the
|
Currently, the Ceph-CSI components may read Secrets and ConfigMaps from the
|
||||||
Tenants namespace. These permissions need to be extended to allow Ceph-CSI to
|
Tenants namespace. These permissions need to be extended to allow Ceph-CSI to
|
||||||
read the contents of the ServiceAccount(s) in the Tenants namespace.
|
read the contents of the ServiceAccount(s) in the Tenants namespace.
|
||||||
|
|
||||||
@ -61,7 +63,8 @@ read the contents of the ServiceAccount(s) in the Tenants namespace.
|
|||||||
|
|
||||||
### Global Configuration
|
### Global Configuration
|
||||||
|
|
||||||
1. a StorageClass links to a KMS configuration by providing the `kmsID` parameter
|
1. a StorageClass links to a KMS configuration by providing the `kmsID`
|
||||||
|
parameter
|
||||||
1. a ConfigMap in the namespace of the Ceph-CSI deployment contains the KMS
|
1. a ConfigMap in the namespace of the Ceph-CSI deployment contains the KMS
|
||||||
configuration for the `kmsID`
|
configuration for the `kmsID`
|
||||||
([`csi-kms-connection-details.yaml`](../../../examples/kms/vault/csi-kms-connection-details.yaml))
|
([`csi-kms-connection-details.yaml`](../../../examples/kms/vault/csi-kms-connection-details.yaml))
|
||||||
@ -76,8 +79,8 @@ configuration from the ConfigMap.
|
|||||||
1. needs ServiceAccount with a known name with permissions to connect to Vault
|
1. needs ServiceAccount with a known name with permissions to connect to Vault
|
||||||
1. optional ConfigMap with options for Vault that override default settings
|
1. optional ConfigMap with options for Vault that override default settings
|
||||||
|
|
||||||
A `CreateVolume` request contains the owner (Namespace) of the Volume.
|
A `CreateVolume` request contains the owner (Namespace) of the Volume. The KMS
|
||||||
The KMS configuration indicates that additional attributes need to be fetched
|
configuration indicates that additional attributes need to be fetched from the
|
||||||
from the Tenants namespace, so the provisioner will fetch these. The additional
|
Tenants namespace, so the provisioner will fetch these. The additional
|
||||||
configuration and ServiceAccount are merged in the provisioners configuration
|
configuration and ServiceAccount are merged in the provisioners' configuration
|
||||||
for the KMS-implementation while creating the volume.
|
for the KMS-implementation while creating the volume.
|
||||||
|
@ -4,7 +4,13 @@ Prior to CSI, Kubernetes provided a powerful volume plugin system. These volume
|
|||||||
plugins were “in-tree” meaning their code was part of the core Kubernetes code
|
plugins were “in-tree” meaning their code was part of the core Kubernetes code
|
||||||
and shipped with the core Kubernetes binaries. The CSI migration effort enables
|
and shipped with the core Kubernetes binaries. The CSI migration effort enables
|
||||||
the replacement of existing in-tree storage plugins such as kubernetes.io/rbd
|
the replacement of existing in-tree storage plugins such as kubernetes.io/rbd
|
||||||
with a corresponding CSI driver. For more information on CSI migration effort
|
with a corresponding CSI driver. This will be an opt-in feature turned on at
|
||||||
|
cluster creation time that will redirect in-tree plugin operations to a
|
||||||
|
corresponding CSI Driver. The main mechanism we will use to migrate plugins is
|
||||||
|
redirecting in-tree operation calls to the CSI Driver instead of the in-tree
|
||||||
|
driver, the external components will pick up these in-tree PV's and use a
|
||||||
|
translation library to translate to CSI Source. For more information on CSI
|
||||||
|
migration effort
|
||||||
refer [design doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/csi-migration.md)
|
refer [design doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/csi-migration.md)
|
||||||
|
|
||||||
## RBD in-tree plugin to CSI migration
|
## RBD in-tree plugin to CSI migration
|
||||||
@ -18,13 +24,17 @@ migration for RBD plugin:
|
|||||||
|
|
||||||
Considering the `clusterID` field is a required one for CSI, but in-tree
|
Considering the `clusterID` field is a required one for CSI, but in-tree
|
||||||
StorageClass has `monitors` field as a required thing the clusterID will be sent
|
StorageClass has `monitors` field as a required thing the clusterID will be sent
|
||||||
from the migration library based on the monitors field, Kubernetes storage admin
|
from the migration library based on the monitors field as like any other CSI
|
||||||
supposed to create a clusterID based on the monitors hash ( ex: `#md5sum <<<
|
request, Kubernetes storage admin supposed to create a clusterID based on the
|
||||||
|
monitors hash ( ex: `#md5sum <<<
|
||||||
"<monaddress:port>"`) in the CSI config map and keep the monitors under this
|
"<monaddress:port>"`) in the CSI config map and keep the monitors under this
|
||||||
configuration before enabling the migration. While CSI driver receive the volume
|
configuration before enabling the migration. While CSI driver receive the volume
|
||||||
ID it will look at the configmap and figure out the monitors to do the
|
ID, it will look at the configmap and figure out the monitors to do the
|
||||||
operations. Thus, CSI operations are unchanged or untouched wrt to the clusterID
|
operations like create volume. Thus, CSI operations are unchanged or untouched
|
||||||
field.
|
wrt to the clusterID field. In other words, for Ceph CSI this is yet another
|
||||||
|
request coming in from a client with required parameters. This is an opaque/NOOP
|
||||||
|
change from the Ceph CSI side for its operations, however mentioning it here as
|
||||||
|
a reference.
|
||||||
|
|
||||||
### New Volume ID for existing volume operations
|
### New Volume ID for existing volume operations
|
||||||
|
|
||||||
@ -45,13 +55,19 @@ Details on the hash values:
|
|||||||
|
|
||||||
* PoolHash: this is an encoded string of pool name.
|
* PoolHash: this is an encoded string of pool name.
|
||||||
|
|
||||||
The existing in-tree volume's node operations should work without any issues as
|
This volume handle is introduced as the existing in-tree volume does not have
|
||||||
those will be tracked as static volumes for the CSI driver. From above volume
|
the volume ID format (
|
||||||
ID, the CSI driver can also connect to the backend cluster and clean/delete the
|
ex: `0001-0020-b7f67366bb43f32e07d8a261a7840da9 -0000000000000002-c867ff35-3f04-11ec-b823-0242ac110003`)
|
||||||
image. The migration volume ID carry the information like monitors, pool and
|
which Ceph CSI use by default. However, Ceph CSI need certain information like
|
||||||
image name which is good enough for the driver to identify and connect to the
|
clusterID, pool, Image name to perform deletion and expansion of the volumes.
|
||||||
backend cluster for its operations. With above volume ID in place, we will be
|
The existing in-tree
|
||||||
able to support mount, unmount, delete and resize operations.
|
volume's `NodeStageVolume, NodePublishVolume, NodeUnstageVolume, NodeUnpublishVolume`
|
||||||
|
operations should work without any issues as those will be tracked as static
|
||||||
|
volumes for the CSI driver. For `DeleteVolume and ControllerExpandVolume`
|
||||||
|
operations, from above migration specific volume ID, the CSI driver can derive
|
||||||
|
the required details and connect to the backend cluster ( as it carry
|
||||||
|
information like monitors, pool and image name) then perform deletion of the
|
||||||
|
image or perform resize operation.
|
||||||
|
|
||||||
### Migration secret for CSI operations
|
### Migration secret for CSI operations
|
||||||
|
|
||||||
@ -68,8 +84,36 @@ field.
|
|||||||
field
|
field
|
||||||
|
|
||||||
if `adminId` field is nil or not set, `UserID` field will be filled with default
|
if `adminId` field is nil or not set, `UserID` field will be filled with default
|
||||||
value ie `admin`.The above logic get activated only when the secret is a
|
value ie `admin`. The above logic get activated only when the secret is a
|
||||||
migration secret, otherwise skipped to the normal workflow as we have today.
|
migration secret, otherwise skipped to the normal workflow as we have today.
|
||||||
|
CreateVolume, DeleteVolume, NodeStage and ExpandVolume has to validate the
|
||||||
|
secret and use for its operations:
|
||||||
|
|
||||||
|
## Helper functions
|
||||||
|
|
||||||
|
Few helper/utility functions will be introduced as part of this effort to handle
|
||||||
|
migration specific logic to it.
|
||||||
|
|
||||||
|
internal/rbd/migration.go
|
||||||
|
|
||||||
|
* isMigrationVolID() - Identify the volume ID is of above-mentioned form of
|
||||||
|
migration volume ID.
|
||||||
|
* parseMigrationVolID() - Parse the migration volume ID and populate the
|
||||||
|
required information like `pool`, `image`, `clusterID`..etc. into
|
||||||
|
`migrationVolID` structure.
|
||||||
|
* deleteMigratedVolume() - Deletes the volume from the cluster by making use of
|
||||||
|
the `migrationVolID` structure fields like `pool, image, clusterID`.
|
||||||
|
|
||||||
|
internal/util/credentials.go
|
||||||
|
|
||||||
|
* isMigrationSecret() - Identify the passed in secret is a migration secret
|
||||||
|
based on the map values (ex: `key` field) of request secret.
|
||||||
|
* NewUserCredentialsWithMigration() - This take request secret map as input and
|
||||||
|
validate whether it is migration secret with the help of isMigrationSecret(),
|
||||||
|
and return credentials by calling NewUserCredentials().
|
||||||
|
* ParseAndSetSecretMapFromMigSecret() - Parse the secret map from the migration
|
||||||
|
request and return a map with adjusted secret fields for the CSI driver to
|
||||||
|
continue performing secret specific operations.
|
||||||
|
|
||||||
## CephFS in-tree plugin to CSI migration
|
## CephFS in-tree plugin to CSI migration
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
# RBD MIRRORING
|
# RBD MIRRORING
|
||||||
|
|
||||||
RBD mirroring is a process of replication of RBD images between two or more
|
RBD mirroring is a process of replication of RBD images between two or more Ceph
|
||||||
Ceph clusters. Mirroring ensures point-in-time, crash-consistent RBD images
|
clusters. Mirroring ensures point-in-time, crash-consistent RBD images between
|
||||||
between clusters, RBD mirroring is mainly used for disaster recovery (i.e.
|
clusters, RBD mirroring is mainly used for disaster recovery (i.e. having a
|
||||||
having a secondary site as a failover). See [Ceph
|
secondary site as a failover).
|
||||||
documentation](https://docs.ceph.com/en/latest/rbd/rbd-mirroring) on RBD
|
See [Ceph documentation](https://docs.ceph.com/en/latest/rbd/rbd-mirroring) on
|
||||||
mirroring for complete information.
|
RBD mirroring for complete information.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
@ -28,8 +28,8 @@ PersistentVolumeClaim (PVC) on the secondary site during the failover.
|
|||||||
VolumeHandle to identify the OMAP data nor the image anymore because as we have
|
VolumeHandle to identify the OMAP data nor the image anymore because as we have
|
||||||
only PoolID and ClusterID in the VolumeHandle. We cannot identify the correct
|
only PoolID and ClusterID in the VolumeHandle. We cannot identify the correct
|
||||||
pool name from the PoolID because pool name will remain the same on both
|
pool name from the PoolID because pool name will remain the same on both
|
||||||
clusters but not the PoolID even the ClusterID can be different on the
|
clusters but not the PoolID even the ClusterID can be different on the secondary
|
||||||
secondary cluster.
|
cluster.
|
||||||
|
|
||||||
> Sample PV spec which will be used by rbdplugin controller to regenerate OMAP
|
> Sample PV spec which will be used by rbdplugin controller to regenerate OMAP
|
||||||
> data
|
> data
|
||||||
@ -56,10 +56,10 @@ csi:
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **VolumeHandle** is the unique volume name returned by the CSI volume plugin’s
|
> **VolumeHandle** is the unique volume name returned by the CSI volume plugin’s
|
||||||
CreateVolume to refer to the volume on all subsequent calls.
|
> CreateVolume to refer to the volume on all subsequent calls.
|
||||||
|
|
||||||
Once the static PVC is created on the secondary cluster, the Kubernetes User
|
Once the static PVC is created on the secondary cluster, the Kubernetes User can
|
||||||
can try delete the PVC,expand the PVC or mount the PVC. In case of mounting
|
try to delete the PVC,expand the PVC or mount the PVC. In case of mounting
|
||||||
(NodeStageVolume) we will get the volume context in RPC call but not in the
|
(NodeStageVolume) we will get the volume context in RPC call but not in the
|
||||||
Delete/Expand Request. In Delete/Expand RPC request only the VolumeHandle
|
Delete/Expand Request. In Delete/Expand RPC request only the VolumeHandle
|
||||||
(`clusterID-poolID-volumeuniqueID`) will be sent where it contains the encoded
|
(`clusterID-poolID-volumeuniqueID`) will be sent where it contains the encoded
|
||||||
@ -73,25 +73,24 @@ secondary cluster as the PoolID and ClusterID always may not be the same.
|
|||||||
|
|
||||||
To solve this problem, We will have a new controller(rbdplugin controller)
|
To solve this problem, We will have a new controller(rbdplugin controller)
|
||||||
running as part of provisioner pod which watches for the PV objects. When a PV
|
running as part of provisioner pod which watches for the PV objects. When a PV
|
||||||
is created it will extract the required information from the PV spec and it
|
is created it will extract the required information from the PV spec, and it
|
||||||
will regenerate the OMAP data and also it will generate a new VolumeHandle
|
will regenerate the OMAP data. Whenever Ceph-CSI gets a RPC request with older
|
||||||
(`newclusterID-newpoolID-volumeuniqueID`) and it adds a PV annotation
|
VolumeHandle, it will check if any new VolumeHandle exists for the old
|
||||||
`csi.ceph.io/volume-handle` for mapping between old VolumeHandle and new
|
VolumeHandle. If yes, it uses the new VolumeHandle for internal operations (to
|
||||||
VolumeHandle. Whenever Ceph-CSI gets a RPC request with older VolumeHandle, it
|
get pool name, Ceph monitor details from the ClusterID etc).
|
||||||
will check if any new VolumeHandle exists for the old VolumeHandle. If yes, it
|
|
||||||
uses the new VolumeHandle for internal operations (to get pool name, Ceph
|
|
||||||
monitor details from the ClusterID etc).
|
|
||||||
|
|
||||||
Currently, We are making use of watchers in node stage request to make sure
|
Currently, We are making use of watchers in node stage request to make sure
|
||||||
ReadWriteOnce (RWO) PVC is mounted on a single node at a given point in time.
|
ReadWriteOnce (RWO) PVC is mounted on a single node at a given point in time. We
|
||||||
We need to change the watchers logic in the node stage request as when we
|
need to change the watchers logic in the node stage request as when we enable
|
||||||
enable the RBD mirroring on an image, a watcher will be added on a RBD image by
|
the RBD mirroring on an image, a watcher will be added on a RBD image by the rbd
|
||||||
the rbd mirroring daemon.
|
mirroring daemon.
|
||||||
|
|
||||||
To solve the ClusterID problem, If the ClusterID is different on the second
|
To solve the ClusterID problem, If the ClusterID is different on the second
|
||||||
cluster, the admin has to create a new ConfigMap for the mapped ClusterID's.
|
cluster, the admin has to create a new ConfigMap for the mapped ClusterID's.
|
||||||
Whenever Ceph-CSI gets a request, it will check if the ClusterID mapping exists
|
Whenever Ceph-CSI gets a request, it will check if the ClusterID mapping exists
|
||||||
and uses the mapped ClusterID to get the information like Ceph monitors etc.
|
and uses the mapped ClusterID to get the information like Ceph monitors etc.
|
||||||
|
Details about creation of clusterID's mapping are available at
|
||||||
|
[clusterID-mapping](./clusterid-mapping.md).
|
||||||
|
|
||||||
**This design does not cover the below items:**
|
**This design does not cover the below items:**
|
||||||
|
|
||||||
|
@ -1,59 +1,57 @@
|
|||||||
# RBD NBD VOLUME HEALER
|
# RBD NBD VOLUME HEALER
|
||||||
|
|
||||||
- [RBD NBD VOLUME HEALER](#rbd-nbd-volume-healer)
|
- [RBD NBD VOLUME HEALER](#rbd-nbd-volume-healer)
|
||||||
- [Rbd Nbd](#rbd-nbd)
|
- [Rbd Nbd](#rbd-nbd)
|
||||||
- [Advantages of userspace mounters](#advantages-of-userspace-mounters)
|
- [Advantages of userspace mounters](#advantages-of-userspace-mounters)
|
||||||
- [Side effects of userspace mounters](#side-effects-of-userspace-mounters)
|
- [Side effects of userspace mounters](#side-effects-of-userspace-mounters)
|
||||||
- [Volume Healer](#volume-healer)
|
- [Volume Healer](#volume-healer)
|
||||||
- [More thoughts](#more-thoughts)
|
- [More thoughts](#more-thoughts)
|
||||||
|
|
||||||
## Rbd nbd
|
## Rbd nbd
|
||||||
|
|
||||||
The rbd CSI plugin will provision new rbd images and attach and mount those
|
The rbd CSI plugin will provision new rbd images and attach and mount those to
|
||||||
to workloads. Currently, the default mounter is krbd, which uses the kernel
|
workloads. Currently, the default mounter is krbd, which uses the kernel rbd
|
||||||
rbd driver to mount the rbd images onto the application pod. Here on
|
driver to mount the rbd images onto the application pod. Here on at Ceph-CSI we
|
||||||
at Ceph-CSI we will also have a userspace way of mounting the rbd images,
|
will also have a userspace way of mounting the rbd images, via rbd-nbd.
|
||||||
via rbd-nbd.
|
|
||||||
|
|
||||||
[Rbd-nbd](https://docs.ceph.com/en/latest/man/8/rbd-nbd/) is a client for
|
[Rbd-nbd](https://docs.ceph.com/en/latest/man/8/rbd-nbd/) is a client for RADOS
|
||||||
RADOS block device (rbd) images like the existing rbd kernel module. It
|
block device (rbd) images like the existing rbd kernel module. It will map an
|
||||||
will map an rbd image to an nbd (Network Block Device) device, allowing
|
rbd image to an nbd (Network Block Device) device, allowing access to it as a
|
||||||
access to it as a regular local block device.
|
regular local block device.
|
||||||
|
|
||||||
![csi-rbd-nbd](./images/csi-rbd-nbd.svg)
|
![csi-rbd-nbd](./images/csi-rbd-nbd.svg)
|
||||||
|
|
||||||
It’s worth making a note that the rbd-nbd processes will run on the
|
It’s worth making a note that the rbd-nbd processes will run on the client-side,
|
||||||
client-side, which is inside the `csi-rbdplugin` node plugin.
|
which is inside the `csi-rbdplugin` node plugin.
|
||||||
|
|
||||||
### Advantages of userspace mounters
|
### Advantages of userspace mounters
|
||||||
|
|
||||||
- It is easier to add features to rbd-nbd as it is released regularly with
|
- It is easier to add features to rbd-nbd as it is released regularly with Ceph,
|
||||||
Ceph, and more difficult and time consuming to add features to the kernel
|
and more difficult and time consuming to add features to the kernel rbd module
|
||||||
rbd module as that is part of the Linux kernel release schedule.
|
as that is part of the Linux kernel release schedule.
|
||||||
- Container upgrades will be independent of the host node, which means if
|
- Container upgrades will be independent of the host node, which means if there
|
||||||
there are any new features with rbd-nbd, we don’t have to reboot the node
|
are any new features with rbd-nbd, we don’t have to reboot the node as the
|
||||||
as the changes will be shipped inside the container.
|
changes will be shipped inside the container.
|
||||||
- Because the container upgrades are host node independent, we will be a
|
- Because the container upgrades are host node independent, we will be a better
|
||||||
better citizen in K8s by switching to the userspace model.
|
citizen in K8s by switching to the userspace model.
|
||||||
- Unlike krbd, rbd-nbd uses librbd user-space library that gets most of the
|
- Unlike krbd, rbd-nbd uses librbd user-space library that gets most of the
|
||||||
development focus, and hence rbd-nbd will be feature-rich.
|
development focus, and hence rbd-nbd will be feature-rich.
|
||||||
- Being entirely kernel space impacts fault-tolerance as any kernel panic
|
- Being entirely kernel space impacts fault-tolerance as any kernel panic
|
||||||
affects a whole node not only a single pod that is using rbd storage.
|
affects a whole node not only a single pod that is using rbd storage. Thanks
|
||||||
Thanks to the rbd-nbd’s userspace design, we are less bothered here, the
|
to the rbd-nbd’s userspace design, we are less bothered here, the krbd is a
|
||||||
krbd is a complete kernel and vendor-specific driver which needs changes
|
complete kernel and vendor-specific driver which needs changes on every
|
||||||
on every feature basis, on the other hand, rbd-nbd depends on NBD generic
|
feature basis, on the other hand, rbd-nbd depends on NBD generic driver, while
|
||||||
driver, while all the vendor-specific logic sits in the userspace. It's
|
all the vendor-specific logic sits in the userspace. It's worth taking note
|
||||||
worth taking note that NBD generic driver is mostly unchanged much from
|
that NBD generic driver is mostly unchanged much from years and consider it to
|
||||||
years and consider it to be much stable. Also given NBD is a generic
|
be much stable. Also given NBD is a generic driver there will be many eyes on
|
||||||
driver there will be many eyes on it compared to the rbd driver.
|
it compared to the rbd driver.
|
||||||
|
|
||||||
### Side effects of userspace mounters
|
### Side effects of userspace mounters
|
||||||
|
|
||||||
Since the rbd-nbd processes run per volume map on the client side i.e.
|
Since the rbd-nbd processes run per volume map on the client side i.e. inside
|
||||||
inside the `csi-rbdplugin` node plugin, a restart of the node plugin will
|
the `csi-rbdplugin` node plugin, a restart of the node plugin will terminate all
|
||||||
terminate all the rbd-nbd processes, and there is no way to restore
|
the rbd-nbd processes, and there is no way to restore these processes back to
|
||||||
these processes back to life currently, which could lead to IO errors
|
life currently, which could lead to IO errors on all the application pods.
|
||||||
on all the application pods.
|
|
||||||
|
|
||||||
![csi-plugin-restart](./images/csi-plugin-restart.svg)
|
![csi-plugin-restart](./images/csi-plugin-restart.svg)
|
||||||
|
|
||||||
@ -61,42 +59,42 @@ This is where the Volume healer could help.
|
|||||||
|
|
||||||
## Volume healer
|
## Volume healer
|
||||||
|
|
||||||
Volume healer runs on the start of rbd node plugin and runs within the
|
Volume healer runs on the start of rbd node plugin and runs within the node
|
||||||
node plugin driver context.
|
plugin driver context.
|
||||||
|
|
||||||
Volume healer does the below,
|
Volume healer does the below,
|
||||||
|
|
||||||
- Get the Volume attachment list for the current node where it is running
|
- Get the Volume attachment list for the current node where it is running
|
||||||
- Filter the volume attachments list through matching driver name and
|
- Filter the volume attachments list through matching driver name and status
|
||||||
status attached
|
attached
|
||||||
- For each volume attachment get the respective PV information and check
|
- For each volume attachment get the respective PV information and check the
|
||||||
the criteria of PV Bound, mounter type
|
criteria of PV Bound, mounter type
|
||||||
- Build the StagingPath where rbd images PVC is mounted, based on the
|
- Build the StagingPath where rbd images PVC is mounted, based on the KUBELET
|
||||||
KUBELET path and PV object
|
path and PV object
|
||||||
- Construct the NodeStageVolume() request and send Request to CSI Driver.
|
- Construct the NodeStageVolume() request and send Request to CSI Driver.
|
||||||
- The NodeStageVolume() has a way to identify calls received from the
|
- The NodeStageVolume() has a way to identify calls received from the healer and
|
||||||
healer and when executed from the healer context, it just runs in the
|
when executed from the healer context, it just runs in the minimal required
|
||||||
minimal required form, where it fetches the previously mapped device to
|
form, where it fetches the previously mapped device to the image, and the
|
||||||
the image, and the respective secrets and finally ensures to bringup the
|
respective secrets and finally ensures to bringup the respective process back
|
||||||
respective process back to life. Thus enabling IO to continue.
|
to life. Thus enabling IO to continue.
|
||||||
|
|
||||||
### More thoughts
|
### More thoughts
|
||||||
|
|
||||||
- Currently the NodeStageVolume() call is safeguarded by the global Ceph-CSI
|
- Currently the NodeStageVolume() call is safeguarded by the global Ceph-CSI
|
||||||
level lock (per volID) that needs to be acquired before doing any of the
|
level lock (per volID) that needs to be acquired before doing any of the
|
||||||
NodeStage, NodeUnstage, NodePublish, NodeUnPulish operations. Hence none
|
NodeStage, NodeUnstage, NodePublish, NodeUnPublish operations. Hence none of
|
||||||
of the operations happen in parallel.
|
the operations happen in parallel.
|
||||||
- Any issues if the NodeUnstage is issued by kubelet?
|
- Any issues if the NodeUnstage is issued by kubelet?
|
||||||
- This can not be a problem as we take a lock at the Ceph-CSI level
|
- This can not be a problem as we take a lock at the Ceph-CSI level
|
||||||
- If the NodeUnstage success, Ceph-CSI will return StagingPath not found
|
- If the NodeUnstage success, Ceph-CSI will return StagingPath not found
|
||||||
error, we can then skip
|
error, we can then skip
|
||||||
- If the NodeUnstage fails with an operation already going on, in the
|
- If the NodeUnstage fails with an operation already going on, in the next
|
||||||
next NodeUnstage the volume gets unmounted
|
NodeUnstage the volume gets unmounted
|
||||||
- What if the PVC is deleted?
|
- What if the PVC is deleted?
|
||||||
- If the PVC is deleted, the volume attachment list might already got
|
- If the PVC is deleted, the volume attachment list might already get
|
||||||
refreshed and entry will be skipped/deleted at the healer.
|
refreshed and entry will be skipped/deleted at the healer.
|
||||||
- For any reason, If the request bails out with Error NotFound, skip the
|
- For any reason, If the request bails out with Error NotFound, skip the
|
||||||
PVC, assuming it might have deleted or the NodeUnstage might have
|
PVC, assuming it might have deleted or the NodeUnstage might have already
|
||||||
already happened.
|
happened.
|
||||||
- The Volume healer currently works with rbd-nbd, but the design can
|
- The Volume healer currently works with rbd-nbd, but the design can
|
||||||
accommodate other userspace mounters (may be ceph-fuse).
|
accommodate other userspace mounters (may be ceph-fuse).
|
@ -13,7 +13,7 @@ it is **highly** encouraged to:
|
|||||||
|
|
||||||
### Workspace and repository setup
|
### Workspace and repository setup
|
||||||
|
|
||||||
* [Download](https://golang.org/dl/) Go (>=1.16.x) and
|
* [Download](https://golang.org/dl/) Go (>=1.17.x) and
|
||||||
[install](https://golang.org/doc/install) it on your system.
|
[install](https://golang.org/doc/install) it on your system.
|
||||||
* Setup the [GOPATH](http://www.g33knotes.org/2014/07/60-second-count-down-to-go.html)
|
* Setup the [GOPATH](http://www.g33knotes.org/2014/07/60-second-count-down-to-go.html)
|
||||||
environment.
|
environment.
|
||||||
|
136
e2e/migration.go
136
e2e/migration.go
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -12,96 +11,6 @@ import (
|
|||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateRBDStaticMigrationPVDeletion(f *framework.Framework, appPath, scName string, isBlock bool) error {
|
|
||||||
opt := make(map[string]string)
|
|
||||||
var (
|
|
||||||
rbdImageName = "kubernetes-dynamic-pvc-e0b45b52-7e09-47d3-8f1b-806995fa4412"
|
|
||||||
pvName = "pv-name"
|
|
||||||
pvcName = "pvc-name"
|
|
||||||
namespace = f.UniqueName
|
|
||||||
sc = scName
|
|
||||||
provisionerAnnKey = "pv.kubernetes.io/provisioned-by"
|
|
||||||
provisionerAnnValue = "rbd.csi.ceph.com"
|
|
||||||
)
|
|
||||||
|
|
||||||
c := f.ClientSet
|
|
||||||
PVAnnMap := make(map[string]string)
|
|
||||||
PVAnnMap[provisionerAnnKey] = provisionerAnnValue
|
|
||||||
mons, err := getMons(rookNamespace, c)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to get mons: %w", err)
|
|
||||||
}
|
|
||||||
mon := strings.Join(mons, ",")
|
|
||||||
size := staticPVSize
|
|
||||||
// create rbd image
|
|
||||||
cmd := fmt.Sprintf(
|
|
||||||
"rbd create %s --size=%s --image-feature=layering %s",
|
|
||||||
rbdImageName,
|
|
||||||
staticPVSize,
|
|
||||||
rbdOptions(defaultRBDPool))
|
|
||||||
|
|
||||||
_, stdErr, err := execCommandInToolBoxPod(f, cmd, rookNamespace)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if stdErr != "" {
|
|
||||||
return fmt.Errorf("failed to create rbd image %s", stdErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
opt["migration"] = "true"
|
|
||||||
opt["clusterID"] = getMonsHash(mon)
|
|
||||||
opt["imageFeatures"] = staticPVImageFeature
|
|
||||||
opt["pool"] = defaultRBDPool
|
|
||||||
opt["staticVolume"] = strconv.FormatBool(true)
|
|
||||||
opt["imageName"] = rbdImageName
|
|
||||||
|
|
||||||
// Make volumeID similar to the migration volumeID
|
|
||||||
volID := composeIntreeMigVolID(mon, rbdImageName)
|
|
||||||
pv := getStaticPV(
|
|
||||||
pvName,
|
|
||||||
volID,
|
|
||||||
size,
|
|
||||||
rbdNodePluginSecretName,
|
|
||||||
cephCSINamespace,
|
|
||||||
sc,
|
|
||||||
provisionerAnnValue,
|
|
||||||
isBlock,
|
|
||||||
opt,
|
|
||||||
PVAnnMap,
|
|
||||||
deletePolicy)
|
|
||||||
|
|
||||||
_, err = c.CoreV1().PersistentVolumes().Create(context.TODO(), pv, metav1.CreateOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("PV Create API error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pvc := getStaticPVC(pvcName, pvName, size, namespace, sc, isBlock)
|
|
||||||
|
|
||||||
_, err = c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Create(context.TODO(), pvc, metav1.CreateOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("PVC Create API error: %w", err)
|
|
||||||
}
|
|
||||||
// bind pvc to app
|
|
||||||
app, err := loadApp(appPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Namespace = namespace
|
|
||||||
app.Spec.Volumes[0].PersistentVolumeClaim.ClaimName = pvcName
|
|
||||||
err = createApp(f.ClientSet, app, deployTimeout)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = deletePVCAndApp("", f, pvc, app)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to delete PVC and application: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// composeIntreeMigVolID create a volID similar to intree migration volID
|
// composeIntreeMigVolID create a volID similar to intree migration volID
|
||||||
// the migration volID format looks like below
|
// the migration volID format looks like below
|
||||||
// mig-mons-<hash>-image-<UUID_<poolhash>
|
// mig-mons-<hash>-image-<UUID_<poolhash>
|
||||||
@ -190,6 +99,7 @@ func createMigrationUserSecretAndSC(f *framework.Framework, scName string) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createMigrationSC create a SC with migration specific secrets and clusterid.
|
||||||
func createMigrationSC(f *framework.Framework, scName string) error {
|
func createMigrationSC(f *framework.Framework, scName string) error {
|
||||||
err := deleteResource(rbdExamplePath + "storageclass.yaml")
|
err := deleteResource(rbdExamplePath + "storageclass.yaml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -203,6 +113,13 @@ func createMigrationSC(f *framework.Framework, scName string) error {
|
|||||||
param["csi.storage.k8s.io/controller-expand-secret-name"] = rbdMigrationProvisionerSecretName
|
param["csi.storage.k8s.io/controller-expand-secret-name"] = rbdMigrationProvisionerSecretName
|
||||||
param["csi.storage.k8s.io/node-stage-secret-namespace"] = cephCSINamespace
|
param["csi.storage.k8s.io/node-stage-secret-namespace"] = cephCSINamespace
|
||||||
param["csi.storage.k8s.io/node-stage-secret-name"] = rbdMigrationNodePluginSecretName
|
param["csi.storage.k8s.io/node-stage-secret-name"] = rbdMigrationNodePluginSecretName
|
||||||
|
mons, err := getMons(rookNamespace, f.ClientSet)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get mons: %w", err)
|
||||||
|
}
|
||||||
|
mon := strings.Join(mons, ",")
|
||||||
|
param["migration"] = "true"
|
||||||
|
param["clusterID"] = getMonsHash(mon)
|
||||||
err = createRBDStorageClass(f.ClientSet, f, scName, nil, param, deletePolicy)
|
err = createRBDStorageClass(f.ClientSet, f, scName, nil, param, deletePolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create storageclass: %w", err)
|
return fmt.Errorf("failed to create storageclass: %w", err)
|
||||||
@ -274,3 +191,40 @@ func deleteProvNodeMigrationSecret(f *framework.Framework, provisionerSecret, no
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setupMigrationCMSecretAndSC create custom configmap, secret and SC for migration tests.
|
||||||
|
func setupMigrationCMSecretAndSC(f *framework.Framework, scName string) error {
|
||||||
|
c := f.ClientSet
|
||||||
|
if scName == "" {
|
||||||
|
scName = defaultSCName
|
||||||
|
}
|
||||||
|
err := generateClusterIDConfigMapForMigration(f, c)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to generate clusterID configmap: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = createMigrationUserSecretAndSC(f, scName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create storageclass: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// tearDownMigrationSetup deletes custom configmap and secret.
|
||||||
|
func tearDownMigrationSetup(f *framework.Framework) error {
|
||||||
|
err := deleteConfigMap(rbdDirPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to delete configmap: %w", err)
|
||||||
|
}
|
||||||
|
err = createConfigMap(rbdDirPath, f.ClientSet, f)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create configmap: %w", err)
|
||||||
|
}
|
||||||
|
err = deleteProvNodeMigrationSecret(f, true, true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to delete migration users and Secrets associated: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
129
e2e/rbd.go
129
e2e/rbd.go
@ -402,37 +402,58 @@ var _ = Describe("RBD", func() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// todo: may be remove the below deletion test later once the migration nodestage tests are adjusted
|
By("validate RBD migration PVC", func() {
|
||||||
// also to have deletion validation through the same.
|
err := setupMigrationCMSecretAndSC(f, "")
|
||||||
By("validate RBD migration+static Block PVC Deletion", func() {
|
|
||||||
err := generateClusterIDConfigMapForMigration(f, c)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e2elog.Failf("failed to generate clusterID configmap: %v", err)
|
e2elog.Failf("failed to setup migration prerequisites: %v", err)
|
||||||
}
|
}
|
||||||
|
err = validatePVCAndAppBinding(pvcPath, appPath, f)
|
||||||
// create a sc with different migration secret
|
|
||||||
err = createMigrationUserSecretAndSC(f, "migrationsc")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e2elog.Failf("failed to create storageclass: %v", err)
|
e2elog.Failf("failed to validate pvc and application binding: %v", err)
|
||||||
}
|
|
||||||
err = validateRBDStaticMigrationPVDeletion(f, rawAppPath, "migrationsc", true)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to validate rbd migrated static block pv: %v", err)
|
|
||||||
}
|
}
|
||||||
// validate created backend rbd images
|
// validate created backend rbd images
|
||||||
validateRBDImageCount(f, 0, defaultRBDPool)
|
validateRBDImageCount(f, 0, defaultRBDPool)
|
||||||
err = deleteConfigMap(rbdDirPath)
|
|
||||||
|
// Block PVC resize
|
||||||
|
err = resizePVCAndValidateSize(rawPvcPath, rawAppPath, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e2elog.Failf("failed to delete configmap: %v", err)
|
e2elog.Failf("failed to resize block PVC: %v", err)
|
||||||
}
|
|
||||||
err = createConfigMap(rbdDirPath, f.ClientSet, f)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to create configmap: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = deleteProvNodeMigrationSecret(f, true, true)
|
// FileSystem PVC resize
|
||||||
|
err = resizePVCAndValidateSize(pvcPath, appPath, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e2elog.Failf("failed to delete migration users and Secrets associated: %v", err)
|
e2elog.Failf("failed to resize filesystem PVC: %v", err)
|
||||||
|
}
|
||||||
|
err = deleteResource(rbdExamplePath + "storageclass.yaml")
|
||||||
|
if err != nil {
|
||||||
|
e2elog.Failf("failed to delete storageclass: %v", err)
|
||||||
|
}
|
||||||
|
err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, nil, deletePolicy)
|
||||||
|
if err != nil {
|
||||||
|
e2elog.Failf("failed to create storageclass: %v", err)
|
||||||
|
}
|
||||||
|
err = tearDownMigrationSetup(f)
|
||||||
|
if err != nil {
|
||||||
|
e2elog.Failf("failed to tear down migration setup: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
By("validate RBD migration+static FileSystem", func() {
|
||||||
|
err := setupMigrationCMSecretAndSC(f, "migrationsc")
|
||||||
|
if err != nil {
|
||||||
|
e2elog.Failf("failed to setup migration prerequisites: %v", err)
|
||||||
|
}
|
||||||
|
// validate filesystem pvc mount
|
||||||
|
err = validateRBDStaticMigrationPVC(f, appPath, "migrationsc", false)
|
||||||
|
if err != nil {
|
||||||
|
e2elog.Failf("failed to validate rbd migrated static file mode pvc: %v", err)
|
||||||
|
}
|
||||||
|
// validate created backend rbd images
|
||||||
|
validateRBDImageCount(f, 0, defaultRBDPool)
|
||||||
|
err = tearDownMigrationSetup(f)
|
||||||
|
if err != nil {
|
||||||
|
e2elog.Failf("failed to tear down migration setup: %v", err)
|
||||||
}
|
}
|
||||||
err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, nil, deletePolicy)
|
err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, nil, deletePolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2117,72 +2138,6 @@ var _ = Describe("RBD", func() {
|
|||||||
validateRBDImageCount(f, 0, defaultRBDPool)
|
validateRBDImageCount(f, 0, defaultRBDPool)
|
||||||
})
|
})
|
||||||
|
|
||||||
By("validate RBD migration+static FileSystem PVC", func() {
|
|
||||||
err := generateClusterIDConfigMapForMigration(f, c)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to generate clusterID configmap: %v", err)
|
|
||||||
}
|
|
||||||
// create node user and migration secret.
|
|
||||||
err = createProvNodeCephUserAndSecret(f, false, true)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to create users and secret: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = validateRBDStaticMigrationPV(f, appPath, rbdMigrationNodePluginSecretName, false)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to validate rbd migrated static pv: %v", err)
|
|
||||||
}
|
|
||||||
// validate created backend rbd images
|
|
||||||
validateRBDImageCount(f, 0, defaultRBDPool)
|
|
||||||
|
|
||||||
err = deleteProvNodeMigrationSecret(f, false, true)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to delete users and secret: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = deleteConfigMap(rbdDirPath)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to delete configmap: %v", err)
|
|
||||||
}
|
|
||||||
err = createConfigMap(rbdDirPath, f.ClientSet, f)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to create configmap: %v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
By("validate RBD migration+static Block PVC", func() {
|
|
||||||
err := generateClusterIDConfigMapForMigration(f, c)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to generate clusterID configmap: %v", err)
|
|
||||||
}
|
|
||||||
// create node user and migration secret.
|
|
||||||
err = createProvNodeCephUserAndSecret(f, false, true)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to create users and secret: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = validateRBDStaticMigrationPV(f, rawAppPath, rbdMigrationNodePluginSecretName, true)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to validate rbd migrated static block pv: %v", err)
|
|
||||||
}
|
|
||||||
// validate created backend rbd images
|
|
||||||
validateRBDImageCount(f, 0, defaultRBDPool)
|
|
||||||
|
|
||||||
err = deleteProvNodeMigrationSecret(f, false, true)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to delete users and secret: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = deleteConfigMap(rbdDirPath)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to delete configmap: %v", err)
|
|
||||||
}
|
|
||||||
err = createConfigMap(rbdDirPath, f.ClientSet, f)
|
|
||||||
if err != nil {
|
|
||||||
e2elog.Failf("failed to create configmap: %v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
By("validate failure of RBD static PVC without imageFeatures parameter", func() {
|
By("validate failure of RBD static PVC without imageFeatures parameter", func() {
|
||||||
err := validateRBDStaticPV(f, rawAppPath, true, true)
|
err := validateRBDStaticPV(f, rawAppPath, true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -22,7 +22,6 @@ const (
|
|||||||
intreeVolPrefix = "kubernetes-dynamic-pvc-"
|
intreeVolPrefix = "kubernetes-dynamic-pvc-"
|
||||||
)
|
)
|
||||||
|
|
||||||
// nolint:unparam // currently name receive pvName, this can change in the future
|
|
||||||
func getStaticPV(
|
func getStaticPV(
|
||||||
name, volName, size, secretName, secretNS, sc, driverName string,
|
name, volName, size, secretName, secretNS, sc, driverName string,
|
||||||
blockPV bool,
|
blockPV bool,
|
||||||
@ -70,7 +69,6 @@ func getStaticPV(
|
|||||||
return pv
|
return pv
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:unparam // currently name receive same name, this can change in the future
|
|
||||||
func getStaticPVC(name, pvName, size, ns, sc string, blockPVC bool) *v1.PersistentVolumeClaim {
|
func getStaticPVC(name, pvName, size, ns, sc string, blockPVC bool) *v1.PersistentVolumeClaim {
|
||||||
pvc := &v1.PersistentVolumeClaim{
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@ -221,19 +219,21 @@ func validateRBDStaticPV(f *framework.Framework, appPath string, isBlock, checkI
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateRBDStaticMigrationPV(f *framework.Framework, appPath, nodeSecretName string, isBlock bool) error {
|
func validateRBDStaticMigrationPVC(f *framework.Framework, appPath, scName string, isBlock bool) error {
|
||||||
opt := make(map[string]string)
|
opt := make(map[string]string)
|
||||||
var (
|
var (
|
||||||
rbdImageName = "test-static-pv"
|
rbdImageName = "kubernetes-dynamic-pvc-e0b45b52-7e09-47d3-8f1b-806995fa4412"
|
||||||
pvName = "pv-name"
|
pvName = "pv-name"
|
||||||
pvcName = "pvc-name"
|
pvcName = "pvc-name"
|
||||||
namespace = f.UniqueName
|
namespace = f.UniqueName
|
||||||
// minikube creates default class in cluster, we need to set dummy
|
sc = scName
|
||||||
// storageclass on PV and PVC to avoid storageclass name mismatch
|
provisionerAnnKey = "pv.kubernetes.io/provisioned-by"
|
||||||
sc = "storage-class"
|
provisionerAnnValue = "rbd.csi.ceph.com"
|
||||||
)
|
)
|
||||||
|
|
||||||
c := f.ClientSet
|
c := f.ClientSet
|
||||||
|
PVAnnMap := make(map[string]string)
|
||||||
|
PVAnnMap[provisionerAnnKey] = provisionerAnnValue
|
||||||
mons, err := getMons(rookNamespace, c)
|
mons, err := getMons(rookNamespace, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get mons: %w", err)
|
return fmt.Errorf("failed to get mons: %w", err)
|
||||||
@ -242,20 +242,17 @@ func validateRBDStaticMigrationPV(f *framework.Framework, appPath, nodeSecretNam
|
|||||||
size := staticPVSize
|
size := staticPVSize
|
||||||
// create rbd image
|
// create rbd image
|
||||||
cmd := fmt.Sprintf(
|
cmd := fmt.Sprintf(
|
||||||
"rbd create %s --size=%d --image-feature=layering %s",
|
"rbd create %s --size=%s --image-feature=layering %s",
|
||||||
rbdImageName,
|
rbdImageName,
|
||||||
4096,
|
staticPVSize,
|
||||||
rbdOptions(defaultRBDPool))
|
rbdOptions(defaultRBDPool))
|
||||||
|
|
||||||
_, e, err := execCommandInToolBoxPod(f, cmd, rookNamespace)
|
_, stdErr, err := execCommandInToolBoxPod(f, cmd, rookNamespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if e != "" {
|
if stdErr != "" {
|
||||||
return fmt.Errorf("failed to create rbd image %s", e)
|
return fmt.Errorf("failed to create rbd image %s", stdErr)
|
||||||
}
|
|
||||||
if nodeSecretName == "" {
|
|
||||||
nodeSecretName = rbdNodePluginSecretName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opt["migration"] = "true"
|
opt["migration"] = "true"
|
||||||
@ -264,16 +261,21 @@ func validateRBDStaticMigrationPV(f *framework.Framework, appPath, nodeSecretNam
|
|||||||
opt["pool"] = defaultRBDPool
|
opt["pool"] = defaultRBDPool
|
||||||
opt["staticVolume"] = strconv.FormatBool(true)
|
opt["staticVolume"] = strconv.FormatBool(true)
|
||||||
opt["imageName"] = rbdImageName
|
opt["imageName"] = rbdImageName
|
||||||
|
|
||||||
|
// Make volumeID similar to the migration volumeID
|
||||||
|
volID := composeIntreeMigVolID(mon, rbdImageName)
|
||||||
pv := getStaticPV(
|
pv := getStaticPV(
|
||||||
pvName,
|
pvName,
|
||||||
rbdImageName,
|
volID,
|
||||||
size,
|
size,
|
||||||
nodeSecretName,
|
rbdNodePluginSecretName,
|
||||||
cephCSINamespace,
|
cephCSINamespace,
|
||||||
sc,
|
sc,
|
||||||
"rbd.csi.ceph.com",
|
provisionerAnnValue,
|
||||||
isBlock,
|
isBlock,
|
||||||
opt, nil, retainPolicy)
|
opt,
|
||||||
|
PVAnnMap,
|
||||||
|
deletePolicy)
|
||||||
|
|
||||||
_, err = c.CoreV1().PersistentVolumes().Create(context.TODO(), pv, metav1.CreateOptions{})
|
_, err = c.CoreV1().PersistentVolumes().Create(context.TODO(), pv, metav1.CreateOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -299,24 +301,11 @@ func validateRBDStaticMigrationPV(f *framework.Framework, appPath, nodeSecretNam
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = deletePod(app.Name, app.Namespace, f.ClientSet, deployTimeout)
|
err = deletePVCAndApp("", f, pvc, app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to delete PVC and application: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(context.TODO(), pvc.Name, metav1.DeleteOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to delete pvc: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = c.CoreV1().PersistentVolumes().Delete(context.TODO(), pv.Name, metav1.DeleteOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to delete pv: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = fmt.Sprintf("rbd rm %s %s", rbdImageName, rbdOptions(defaultRBDPool))
|
|
||||||
_, _, err = execCommandInToolBoxPod(f, cmd, rookNamespace)
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,5 +60,12 @@ data:
|
|||||||
"KMS_SECRET_NAME": "ceph-csi-aws-credentials",
|
"KMS_SECRET_NAME": "ceph-csi-aws-credentials",
|
||||||
"AWS_REGION": "us-west-2"
|
"AWS_REGION": "us-west-2"
|
||||||
}
|
}
|
||||||
|
kp-metadata-test: |-
|
||||||
|
{
|
||||||
|
"KMS_PROVIDER": "kp-metadata",
|
||||||
|
"KMS_SECRET_NAME": "ceph-csi-kp-credentials",
|
||||||
|
"KP_SERVICE_INSTANCE_ID": "7abef064-01dd-4237-9ea5-8b3890970be3",
|
||||||
|
"KP_REGION": "us-south-2",
|
||||||
|
}
|
||||||
metadata:
|
metadata:
|
||||||
name: csi-kms-connection-details
|
name: csi-kms-connection-details
|
||||||
|
@ -90,6 +90,12 @@ data:
|
|||||||
"user-secrets-metadata-test": {
|
"user-secrets-metadata-test": {
|
||||||
"encryptionKMSType": "metadata",
|
"encryptionKMSType": "metadata",
|
||||||
"secretName": "storage-encryption-secret"
|
"secretName": "storage-encryption-secret"
|
||||||
|
},
|
||||||
|
"kp-metadata-test": {
|
||||||
|
"encryptionKMSType": "kp-metadata",
|
||||||
|
"secretName": "ceph-csi-kp-credentials",
|
||||||
|
"keyProtectRegionKey": "us-south-2",
|
||||||
|
"keyProtectServiceInstanceID": "7abef064-01dd-4237-9ea5-8b3890970be3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
metadata:
|
metadata:
|
||||||
|
13
examples/kms/vault/kp-credentials.yaml
Normal file
13
examples/kms/vault/kp-credentials.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
# This is an example Kubernetes Secret that can be created in the Kubernetes
|
||||||
|
# Namespace where Ceph-CSI is deployed. The contents of this Secret will be
|
||||||
|
# used to connect to the Key Protect KMS.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ceph-csi-kp-credentials
|
||||||
|
stringData:
|
||||||
|
KP_SERVICE_API_KEY: "UhMN3Jko1pCpDPpFV65N8dYANBv5vF97QuNHqXVHmKa0"
|
||||||
|
KP_CUSTOMER_ROOT_KEY: "c7a9aa91-5cb5-48da-a821-e85c27b99d92"
|
||||||
|
KP_SESSION_TOKEN: ""
|
||||||
|
KP_CRK_ARN: ""
|
187
go.mod
187
go.mod
@ -1,15 +1,15 @@
|
|||||||
module github.com/ceph/ceph-csi
|
module github.com/ceph/ceph-csi
|
||||||
|
|
||||||
go 1.16
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/IBM/keyprotect-go-client v0.7.0
|
||||||
github.com/aws/aws-sdk-go v1.42.7
|
github.com/aws/aws-sdk-go v1.42.7
|
||||||
github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000
|
github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000
|
||||||
github.com/ceph/go-ceph v0.12.0
|
github.com/ceph/go-ceph v0.12.0
|
||||||
github.com/container-storage-interface/spec v1.5.0
|
github.com/container-storage-interface/spec v1.5.0
|
||||||
github.com/csi-addons/replication-lib-utils v0.2.0
|
github.com/csi-addons/replication-lib-utils v0.2.0
|
||||||
github.com/csi-addons/spec v0.1.2-0.20211123125058-fd968c478af7
|
github.com/csi-addons/spec v0.1.2-0.20211123125058-fd968c478af7
|
||||||
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
|
||||||
github.com/golang/protobuf v1.5.2
|
github.com/golang/protobuf v1.5.2
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||||
@ -22,22 +22,133 @@ require (
|
|||||||
github.com/pborman/uuid v1.2.1
|
github.com/pborman/uuid v1.2.1
|
||||||
github.com/prometheus/client_golang v1.11.0
|
github.com/prometheus/client_golang v1.11.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||||
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2
|
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8
|
||||||
google.golang.org/grpc v1.42.0
|
google.golang.org/grpc v1.42.0
|
||||||
google.golang.org/protobuf v1.26.0
|
google.golang.org/protobuf v1.27.1
|
||||||
k8s.io/api v0.22.4
|
k8s.io/api v0.23.0
|
||||||
k8s.io/apimachinery v0.22.4
|
k8s.io/apimachinery v0.23.0
|
||||||
k8s.io/client-go v12.0.0+incompatible
|
k8s.io/client-go v12.0.0+incompatible
|
||||||
k8s.io/cloud-provider v0.22.4
|
k8s.io/cloud-provider v0.23.0
|
||||||
k8s.io/klog/v2 v2.10.0
|
k8s.io/klog/v2 v2.30.0
|
||||||
//
|
//
|
||||||
// when updating k8s.io/kubernetes, make sure to update the replace section too
|
// when updating k8s.io/kubernetes, make sure to update the replace section too
|
||||||
//
|
//
|
||||||
k8s.io/kubernetes v1.22.4
|
k8s.io/kubernetes v1.23.0
|
||||||
k8s.io/mount-utils v0.22.4
|
k8s.io/mount-utils v0.23.0
|
||||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a
|
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b
|
||||||
sigs.k8s.io/controller-runtime v0.10.3
|
sigs.k8s.io/controller-runtime v0.11.0-beta.0.0.20211208212546-f236f0345ad2
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/armon/go-metrics v0.3.9 // indirect
|
||||||
|
github.com/armon/go-radix v1.0.0 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/bits-and-blooms/bitset v1.2.0 // indirect
|
||||||
|
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||||
|
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||||
|
github.com/cyphar/filepath-securejoin v0.2.2 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||||
|
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
||||||
|
github.com/fatih/color v1.9.0 // indirect
|
||||||
|
github.com/felixge/httpsnoop v1.0.1 // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||||
|
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
|
||||||
|
github.com/go-logr/logr v1.2.0 // indirect
|
||||||
|
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/go-cmp v0.5.5 // indirect
|
||||||
|
github.com/google/gofuzz v1.1.0 // indirect
|
||||||
|
github.com/google/uuid v1.1.2 // indirect
|
||||||
|
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
|
||||||
|
github.com/hashicorp/go-hclog v0.16.2 // indirect
|
||||||
|
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
github.com/hashicorp/go-plugin v1.4.3 // indirect
|
||||||
|
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
|
||||||
|
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||||
|
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect
|
||||||
|
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 // indirect
|
||||||
|
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 // indirect
|
||||||
|
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
|
||||||
|
github.com/hashicorp/go-uuid v1.0.2 // indirect
|
||||||
|
github.com/hashicorp/go-version v1.2.0 // indirect
|
||||||
|
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/hashicorp/vault v1.4.2 // indirect
|
||||||
|
github.com/hashicorp/vault/sdk v0.3.0 // indirect
|
||||||
|
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
|
||||||
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||||
|
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
|
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.4.2 // indirect
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.1 // indirect
|
||||||
|
github.com/moby/spdystream v0.2.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/nxadm/tail v1.4.8 // indirect
|
||||||
|
github.com/oklog/run v1.0.0 // indirect
|
||||||
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
|
github.com/opencontainers/runc v1.0.2 // indirect
|
||||||
|
github.com/opencontainers/selinux v1.8.2 // indirect
|
||||||
|
github.com/openshift/api v0.0.0-20210927171657-636513e97fda // indirect
|
||||||
|
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
|
github.com/prometheus/common v0.28.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.6.0 // indirect
|
||||||
|
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||||
|
github.com/spf13/cobra v1.2.1 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
go.opentelemetry.io/contrib v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/sdk v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/sdk/export/metric v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/proto/otlp v0.7.0 // indirect
|
||||||
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20210825183410-e898025ed96a // indirect
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
|
||||||
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||||
|
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2 // indirect
|
||||||
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
|
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
|
k8s.io/apiserver v0.23.0 // indirect
|
||||||
|
k8s.io/component-base v0.23.0 // indirect
|
||||||
|
k8s.io/component-helpers v0.23.0 // indirect
|
||||||
|
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
|
||||||
|
k8s.io/kubectl v0.0.0 // indirect
|
||||||
|
k8s.io/kubelet v0.0.0 // indirect
|
||||||
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25 // indirect
|
||||||
|
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
@ -49,31 +160,31 @@ replace (
|
|||||||
//
|
//
|
||||||
// k8s.io/kubernetes depends on these k8s.io packages, but unversioned
|
// k8s.io/kubernetes depends on these k8s.io packages, but unversioned
|
||||||
//
|
//
|
||||||
k8s.io/api => k8s.io/api v0.22.4
|
k8s.io/api => k8s.io/api v0.23.0
|
||||||
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.22.4
|
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.23.0
|
||||||
k8s.io/apimachinery => k8s.io/apimachinery v0.22.4
|
k8s.io/apimachinery => k8s.io/apimachinery v0.23.0
|
||||||
k8s.io/apiserver => k8s.io/apiserver v0.22.4
|
k8s.io/apiserver => k8s.io/apiserver v0.23.0
|
||||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.22.4
|
k8s.io/cli-runtime => k8s.io/cli-runtime v0.23.0
|
||||||
k8s.io/client-go => k8s.io/client-go v0.22.4
|
k8s.io/client-go => k8s.io/client-go v0.23.0
|
||||||
k8s.io/cloud-provider => k8s.io/cloud-provider v0.22.4
|
k8s.io/cloud-provider => k8s.io/cloud-provider v0.23.0
|
||||||
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.22.4
|
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.23.0
|
||||||
k8s.io/code-generator => k8s.io/code-generator v0.22.4
|
k8s.io/code-generator => k8s.io/code-generator v0.23.0
|
||||||
k8s.io/component-base => k8s.io/component-base v0.22.4
|
k8s.io/component-base => k8s.io/component-base v0.23.0
|
||||||
k8s.io/component-helpers => k8s.io/component-helpers v0.22.4
|
k8s.io/component-helpers => k8s.io/component-helpers v0.23.0
|
||||||
k8s.io/controller-manager => k8s.io/controller-manager v0.22.4
|
k8s.io/controller-manager => k8s.io/controller-manager v0.23.0
|
||||||
k8s.io/cri-api => k8s.io/cri-api v0.22.4
|
k8s.io/cri-api => k8s.io/cri-api v0.23.0
|
||||||
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.22.4
|
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.23.0
|
||||||
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.22.4
|
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.23.0
|
||||||
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.22.4
|
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.23.0
|
||||||
k8s.io/kube-proxy => k8s.io/kube-proxy v0.22.4
|
k8s.io/kube-proxy => k8s.io/kube-proxy v0.23.0
|
||||||
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.22.4
|
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.23.0
|
||||||
k8s.io/kubectl => k8s.io/kubectl v0.22.4
|
k8s.io/kubectl => k8s.io/kubectl v0.23.0
|
||||||
k8s.io/kubelet => k8s.io/kubelet v0.22.4
|
k8s.io/kubelet => k8s.io/kubelet v0.23.0
|
||||||
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.22.4
|
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.23.0
|
||||||
k8s.io/metrics => k8s.io/metrics v0.22.4
|
k8s.io/metrics => k8s.io/metrics v0.23.0
|
||||||
k8s.io/mount-utils => k8s.io/mount-utils v0.22.4
|
k8s.io/mount-utils => k8s.io/mount-utils v0.23.0
|
||||||
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.22.4
|
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.23.0
|
||||||
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.22.4
|
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.23.0
|
||||||
// layeh.com seems to be misbehaving
|
// layeh.com seems to be misbehaving
|
||||||
layeh.com/radius => github.com/layeh/radius v0.0.0-20190322222518-890bc1058917
|
layeh.com/radius => github.com/layeh/radius v0.0.0-20190322222518-890bc1058917
|
||||||
)
|
)
|
||||||
|
332
go.sum
332
go.sum
@ -1,3 +1,4 @@
|
|||||||
|
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
||||||
bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM=
|
bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM=
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
@ -9,7 +10,6 @@ cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK
|
|||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||||
cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
|
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||||
@ -17,6 +17,11 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
|
|||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||||
|
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||||
|
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||||
|
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||||
|
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||||
|
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||||
@ -73,17 +78,19 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
|||||||
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ=
|
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.16.1-0.20210702024009-ea6160c1d0e3/go.mod h1:8XasY4ymP2V/tn2OOV9ZadmiTE1FIB/h3W+yNlPttKw=
|
||||||
github.com/IBM/keyprotect-go-client v0.5.1/go.mod h1:5TwDM/4FRJq1ZOlwQL1xFahLWQ3TveR88VmL1u3njyI=
|
github.com/IBM/keyprotect-go-client v0.5.1/go.mod h1:5TwDM/4FRJq1ZOlwQL1xFahLWQ3TveR88VmL1u3njyI=
|
||||||
|
github.com/IBM/keyprotect-go-client v0.7.0 h1:JstSHD14Lp6ihwQseyPuGcs1AjOBjAmcisP0dTBA6A0=
|
||||||
|
github.com/IBM/keyprotect-go-client v0.7.0/go.mod h1:SVr2ylV/fhSQPDiUjWirN9fsyWFCNNbt8GIT8hPJVjE=
|
||||||
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA=
|
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA=
|
||||||
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
|
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
|
||||||
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
|
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
|
||||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
|
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
|
||||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
github.com/Microsoft/go-winio v0.4.13/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
github.com/Microsoft/go-winio v0.4.13/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
|
||||||
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||||
github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990/go.mod h1:ay/0dTb7NsG8QMDfsRfLHgZo/6xAJShLe1+ePPflihk=
|
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
|
github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||||
@ -108,6 +115,7 @@ github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190412020505-60e2075261b6/go.mod
|
|||||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ=
|
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ=
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2/go.mod h1:OMVSB21p9+xQUIqlGizHPZfjK+SHws1ht+ZytVDoz9U=
|
github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2/go.mod h1:OMVSB21p9+xQUIqlGizHPZfjK+SHws1ht+ZytVDoz9U=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
@ -146,6 +154,7 @@ github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCS
|
|||||||
github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA=
|
github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA=
|
||||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
|
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
||||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
@ -173,8 +182,7 @@ github.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0/go.mod h1:5d
|
|||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||||
github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
|
||||||
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||||
@ -183,8 +191,10 @@ github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381
|
|||||||
github.com/cloudfoundry/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:Zv7xtAh/T/tmfZlxpESaWWiWOdiJz2GfbBYxImuI6T4=
|
github.com/cloudfoundry/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:Zv7xtAh/T/tmfZlxpESaWWiWOdiJz2GfbBYxImuI6T4=
|
||||||
github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0=
|
github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||||
|
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
@ -197,21 +207,20 @@ github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u9
|
|||||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
||||||
github.com/container-storage-interface/spec v1.5.0 h1:lvKxe3uLgqQeVQcrnL2CPQKISoKjTJxojEs9cBk+HXo=
|
github.com/container-storage-interface/spec v1.5.0 h1:lvKxe3uLgqQeVQcrnL2CPQKISoKjTJxojEs9cBk+HXo=
|
||||||
github.com/container-storage-interface/spec v1.5.0/go.mod h1:8K96oQNkJ7pFcC2R9Z1ynGGBB1I93kcS6PGg3SsOk8s=
|
github.com/container-storage-interface/spec v1.5.0/go.mod h1:8K96oQNkJ7pFcC2R9Z1ynGGBB1I93kcS6PGg3SsOk8s=
|
||||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
|
||||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
|
||||||
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||||
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||||
github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
github.com/containerd/containerd v1.4.11/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||||
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
|
||||||
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
|
|
||||||
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||||
github.com/coredns/caddy v1.1.0/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4=
|
github.com/coredns/caddy v1.1.0/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4=
|
||||||
github.com/coredns/corefile-migration v1.0.12/go.mod h1:NJOI8ceUF/NTgEwtjD+TUq3/BnH/GF7WAM3RzCa3hBo=
|
github.com/coredns/corefile-migration v1.0.14/go.mod h1:XnhgULOEouimnzgn0t4WPuFDN2/PJQcTxdWKC5eXNGE=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
@ -222,8 +231,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
|||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
@ -253,10 +261,9 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
|
|||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
|
||||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
@ -282,15 +289,18 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
|
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
|
||||||
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
||||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
|
|
||||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
|
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
|
||||||
|
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/evanphx/json-patch/v5 v5.5.0 h1:bAmFiUJ+o0o2B4OiTFeE3MqCOtyo+jjPP9iZ0VRxYUc=
|
github.com/evanphx/json-patch/v5 v5.5.0 h1:bAmFiUJ+o0o2B4OiTFeE3MqCOtyo+jjPP9iZ0VRxYUc=
|
||||||
github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
|
github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||||
@ -313,12 +323,14 @@ github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM
|
|||||||
github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk=
|
github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk=
|
||||||
github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU=
|
github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
|
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||||
|
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
||||||
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||||
github.com/gammazero/deque v0.0.0-20190130191400-2afb3858e9c7/go.mod h1:GeIq9qoE43YdGnDXURnmKTnGg15pQz4mYkXSTChbneI=
|
github.com/gammazero/deque v0.0.0-20190130191400-2afb3858e9c7/go.mod h1:GeIq9qoE43YdGnDXURnmKTnGg15pQz4mYkXSTChbneI=
|
||||||
github.com/gammazero/workerpool v0.0.0-20190406235159-88d534f22b56/go.mod h1:w9RqFVO2BM3xwWEcAB8Fwp0OviTBBEiRmSBDfbXnd3w=
|
github.com/gammazero/workerpool v0.0.0-20190406235159-88d534f22b56/go.mod h1:w9RqFVO2BM3xwWEcAB8Fwp0OviTBBEiRmSBDfbXnd3w=
|
||||||
|
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
||||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew=
|
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew=
|
||||||
@ -339,11 +351,12 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
|||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
|
||||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
|
github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
|
||||||
|
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
||||||
github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM=
|
github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk=
|
||||||
github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
|
||||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||||
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
|
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
|
||||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||||
@ -379,6 +392,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
|
|||||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
||||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/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-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
@ -395,6 +409,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
|||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||||
|
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
@ -408,7 +423,9 @@ github.com/gomodules/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DK
|
|||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/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/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||||
github.com/google/cadvisor v0.39.2/go.mod h1:kN93gpdevu+bpS227TyHVZyCU5bbqCzTj5T9drl34MI=
|
github.com/google/cadvisor v0.43.0/go.mod h1:+RdMSbc3FVr5NYCD2dOEJy/LI0jYJ/0xJXkzWXEyiFQ=
|
||||||
|
github.com/google/cel-go v0.9.0/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w=
|
||||||
|
github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
@ -417,6 +434,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
@ -429,6 +447,7 @@ github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
|||||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
|
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
github.com/google/pprof v0.0.0-20181127221834-b4f47329b966/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181127221834-b4f47329b966/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
@ -437,6 +456,10 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
|
|||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
|
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
|
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
|
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
|
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
@ -477,6 +500,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
|
|||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||||
github.com/hashicorp/consul-template v0.25.0/go.mod h1:/vUsrJvDuuQHcxEw0zik+YXTS7ZKWZjQeaQhshBmfH0=
|
github.com/hashicorp/consul-template v0.25.0/go.mod h1:/vUsrJvDuuQHcxEw0zik+YXTS7ZKWZjQeaQhshBmfH0=
|
||||||
@ -628,6 +652,7 @@ github.com/heketi/heketi v10.3.0+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva
|
|||||||
github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4=
|
github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
@ -668,8 +693,9 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
|||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
@ -690,6 +716,7 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
|
|||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
@ -719,6 +746,7 @@ github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z
|
|||||||
github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA=
|
github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
@ -781,8 +809,9 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
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/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 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/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
github.com/mongodb/go-client-mongodb-atlas v0.1.2/go.mod h1:LS8O0YLkA+sbtOb3fZLF10yY3tJM+1xATXMJ3oU35LU=
|
github.com/mongodb/go-client-mongodb-atlas v0.1.2/go.mod h1:LS8O0YLkA+sbtOb3fZLF10yY3tJM+1xATXMJ3oU35LU=
|
||||||
@ -826,22 +855,18 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
|||||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
|
|
||||||
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
|
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
|
||||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
|
||||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
|
||||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||||
github.com/opencontainers/runc v1.0.0-rc95/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM=
|
|
||||||
github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
|
github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
|
||||||
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
|
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
|
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
|
||||||
github.com/opencontainers/selinux v1.8.2 h1:c4ca10UMgRcvZ6h0K4HtS15UaVSBEaE+iln2LVpAuGc=
|
github.com/opencontainers/selinux v1.8.2 h1:c4ca10UMgRcvZ6h0K4HtS15UaVSBEaE+iln2LVpAuGc=
|
||||||
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
||||||
github.com/openshift/api v0.0.0-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg=
|
github.com/openshift/api v0.0.0-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg=
|
||||||
@ -869,6 +894,7 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
|
|||||||
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
|
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
|
||||||
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pierrec/lz4 v2.2.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.2.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
@ -879,6 +905,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/portworx/dcos-secrets v0.0.0-20180616013705-8e8ec3f66611/go.mod h1:4hklRW/4DQpLqkcXcjtNprbH2tz/sJaNtqinfPWl/LA=
|
github.com/portworx/dcos-secrets v0.0.0-20180616013705-8e8ec3f66611/go.mod h1:4hklRW/4DQpLqkcXcjtNprbH2tz/sJaNtqinfPWl/LA=
|
||||||
@ -918,9 +945,9 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
|||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
|
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/common v0.28.0 h1:vGVfV9KrDTvWt5boZO0I19g2E3CsWfpPPKZM9dt3mEw=
|
||||||
|
github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
@ -930,7 +957,6 @@ github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7z
|
|||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
|
||||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
@ -977,14 +1003,18 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
|
|||||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
|
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||||
|
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
|
|
||||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||||
|
github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw=
|
||||||
|
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
@ -993,6 +1023,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||||
|
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY=
|
github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY=
|
||||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
@ -1024,7 +1055,6 @@ github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYp
|
|||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||||
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
|
||||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||||
@ -1036,6 +1066,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||||
@ -1057,6 +1088,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
|||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
|
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||||
|
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||||
go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
|
go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
|
||||||
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
|
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
|
||||||
@ -1086,16 +1119,19 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
|||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
|
||||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
|
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
|
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||||
|
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||||
go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
|
|
||||||
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||||
|
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
|
||||||
|
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||||
golang.org/x/arch v0.0.0-20180920145803-b19384d3c130/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
|
golang.org/x/arch v0.0.0-20180920145803-b19384d3c130/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
|
||||||
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
@ -1108,14 +1144,15 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||||
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@ -1147,7 +1184,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
|||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
@ -1160,6 +1197,8 @@ golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hM
|
|||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -1185,7 +1224,6 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@ -1203,15 +1241,23 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
|||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
|
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20210825183410-e898025ed96a h1:bRuuGXV8wwSdGTB+CtJf+FjgO1APK1CoO39T4BN/XBw=
|
||||||
|
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -1221,8 +1267,17 @@ golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4Iltr
|
|||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5 h1:Lm4OryKCca1vehdsWogr9N4t7NfZxLbJoc/H0w4K4S4=
|
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -1296,27 +1351,40 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 h1:M69LAlWZCshgp0QSzyDcSsSIejIEeuaCVpmwcKwyLMk=
|
||||||
|
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
||||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
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.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -1325,14 +1393,14 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/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-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
||||||
@ -1393,10 +1461,17 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
|
|||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
|
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||||
|
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
|
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@ -1421,7 +1496,6 @@ google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn
|
|||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||||
google.golang.org/api v0.15.1-0.20200106000736-b8fc810ca6b5/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||||
@ -1431,6 +1505,13 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
|
|||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||||
|
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||||
|
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||||
|
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||||
|
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||||
|
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||||
|
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||||
|
google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
@ -1478,11 +1559,22 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
|
|||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
|
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||||
|
google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||||
|
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2 h1:NHN4wOCScVzKhPenJ2dt+BTs3X/XkBVI/Rh4iDt55T8=
|
||||||
|
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||||
@ -1503,23 +1595,29 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
|
|||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
|
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
|
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
|
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
|
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||||
google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A=
|
google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A=
|
||||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||||
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
|
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||||
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@ -1531,11 +1629,13 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS
|
|||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||||
|
gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=
|
||||||
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
|
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
|
||||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||||
gopkg.in/ldap.v3 v3.0.3/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
|
gopkg.in/ldap.v3 v3.0.3/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
|
||||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
@ -1578,63 +1678,65 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.22.4 h1:UvyHW0ezB2oIgHAxlYoo6UJQObYXU7awuNarwoHEOjw=
|
k8s.io/api v0.23.0 h1:WrL1gb73VSC8obi8cuYETJGXEoFNEh3LU0Pt+Sokgro=
|
||||||
k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk=
|
k8s.io/api v0.23.0/go.mod h1:8wmDdLBHBNxtOIytwLstXt5E9PddnZb0GaMcqsvDBpg=
|
||||||
k8s.io/apiextensions-apiserver v0.22.4 h1:2iGpcVyw4MnAyyXVJU2Xg6ZsbIxAOfRHo0LF5A5J0RA=
|
k8s.io/apiextensions-apiserver v0.23.0 h1:uii8BYmHYiT2ZTAJxmvc3X8UhNYMxl2A0z0Xq3Pm+WY=
|
||||||
k8s.io/apiextensions-apiserver v0.22.4/go.mod h1:kH9lxD8dbJ+k0ZizGET55lFgdGjO8t45fgZnCVdZEpw=
|
k8s.io/apiextensions-apiserver v0.23.0/go.mod h1:xIFAEEDlAZgpVBl/1VSjGDmLoXAWRG40+GsWhKhAxY4=
|
||||||
k8s.io/apimachinery v0.22.4 h1:9uwcvPpukBw/Ri0EUmWz+49cnFtaoiyEhQTK+xOe7Ck=
|
k8s.io/apimachinery v0.23.0 h1:mIfWRMjBuMdolAWJ3Fd+aPTMv3X9z+waiARMpvvb0HQ=
|
||||||
k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0=
|
k8s.io/apimachinery v0.23.0/go.mod h1:fFCTTBKvKcwTPFzjlcxp91uPFZr+JA0FubU4fLzzFYc=
|
||||||
k8s.io/apiserver v0.22.4 h1:L+220cy+94UWmyBl1kiVTklBXrBtKsbjlPV60eL2u6s=
|
k8s.io/apiserver v0.23.0 h1:Ds/QveXWi9aJ8ISB0CJa4zBNc5njxAs5u3rmMIexqCY=
|
||||||
k8s.io/apiserver v0.22.4/go.mod h1:38WmcUZiiy41A7Aty8/VorWRa8vDGqoUzDf2XYlku0E=
|
k8s.io/apiserver v0.23.0/go.mod h1:Cec35u/9zAepDPPFyT+UMrgqOCjgJ5qtfVJDxjZYmt4=
|
||||||
k8s.io/cli-runtime v0.22.4/go.mod h1:x35r0ERHXr/MrbR1C6MPJxQ3xKG6+hXi9m2xLzlMPZA=
|
k8s.io/cli-runtime v0.23.0/go.mod h1:B5N3YH0KP1iKr6gEuJ/RRmGjO0mJQ/f/JrsmEiPQAlU=
|
||||||
k8s.io/client-go v0.22.4 h1:aAQ1Wk+I3bjCNk35YWUqbaueqrIonkfDPJSPDDe8Kfg=
|
k8s.io/client-go v0.23.0 h1:vcsOqyPq7XV3QmQRCBH/t9BICJM9Q1M18qahjv+rebY=
|
||||||
k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA=
|
k8s.io/client-go v0.23.0/go.mod h1:hrDnpnK1mSr65lHHcUuIZIXDgEbzc7/683c6hyG4jTA=
|
||||||
k8s.io/cloud-provider v0.22.4 h1:dNCY8e7XESvDvldkX1/PHsJQWEzGyKN1xxS51GuVQuc=
|
k8s.io/cloud-provider v0.23.0 h1:9LATZJu57XanN7po4Xfj6jTLp44uhKiu5Xa3+3Cutz0=
|
||||||
k8s.io/cloud-provider v0.22.4/go.mod h1:lTaIKDEqJt7UPbsz9sk1Aa719ADIWuFtbh/mgq72UE8=
|
k8s.io/cloud-provider v0.23.0/go.mod h1:vY9zulPUCjwCg9TBMh5Qi42JUZUNecQNF7FojNELWws=
|
||||||
k8s.io/cluster-bootstrap v0.22.4/go.mod h1:fTQZ6u9G6fg2LHhB8nEgZLnXIhCDSRYuLUUS5pgW8RY=
|
k8s.io/cluster-bootstrap v0.23.0/go.mod h1:VltEnKWfrRTiKgOXp3ts3vh7yqNlH6KFKFflo9GtCBg=
|
||||||
k8s.io/code-generator v0.22.4/go.mod h1:qjYl54pQ/emhkT0UxbufbREYJMWsHNNV/jSVwhYZQGw=
|
k8s.io/code-generator v0.23.0/go.mod h1:vQvOhDXhuzqiVfM/YHp+dmg10WDZCchJVObc9MvowsE=
|
||||||
k8s.io/component-base v0.22.4 h1:7qwLJnua2ppGNZrRGDQ0vhsFebI39VGbZ4zdR5ArViI=
|
k8s.io/component-base v0.23.0 h1:UAnyzjvVZ2ZR1lF35YwtNY6VMN94WtOnArcXBu34es8=
|
||||||
k8s.io/component-base v0.22.4/go.mod h1:MrSaQy4a3tFVViff8TZL6JHYSewNCLshZCwHYM58v5A=
|
k8s.io/component-base v0.23.0/go.mod h1:DHH5uiFvLC1edCpvcTDV++NKULdYYU6pR9Tt3HIKMKI=
|
||||||
k8s.io/component-helpers v0.22.4 h1:Pso4iXoY6aYLCYQlNkME2MSJvAXo/7lnJYsWHdC6tvE=
|
k8s.io/component-helpers v0.23.0 h1:qNbqN10QTefiWcCOPkHL/0nn81sdKVv6ZgEXcSyot/U=
|
||||||
k8s.io/component-helpers v0.22.4/go.mod h1:A50qTyczDFbhZDifIfS2zFrHuPk9UNOWPpvNZ+3RSIs=
|
k8s.io/component-helpers v0.23.0/go.mod h1:liXMh6FZS4qamKtMJQ7uLHnFe3tlC86RX5mJEk/aerg=
|
||||||
k8s.io/controller-manager v0.22.4/go.mod h1:DcJNoo4OvXCh9KfESIrX9C9dNQj1OfQrAZrEkFbNMRw=
|
k8s.io/controller-manager v0.23.0/go.mod h1:6/IKItSv6p9FY3mSbHgsOYmt4y+HDxiC5hEFg9rJVc8=
|
||||||
k8s.io/cri-api v0.22.4/go.mod h1:mj5DGUtElRyErU5AZ8EM0ahxbElYsaLAMTPhLPQ40Eg=
|
k8s.io/cri-api v0.23.0/go.mod h1:2edENu3/mkyW3c6fVPPPaVGEFbLRacJizBbSp7ZOLOo=
|
||||||
k8s.io/csi-translation-lib v0.22.4/go.mod h1:8ZHJ0R2rSiL+0OC7WEF9MTMW4+CV4YEzXDng3rogEY4=
|
k8s.io/csi-translation-lib v0.23.0/go.mod h1:ho0ljka+BEcdlvFrG08L8FpYi6QJeSGgQLWeVOAeeM8=
|
||||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
|
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
|
||||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||||
k8s.io/klog/v2 v2.10.0 h1:R2HDMDJsHVTHA2n4RjwbeYXdOcBymXdX/JRb1v0VGhE=
|
k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw=
|
||||||
k8s.io/klog/v2 v2.10.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||||
k8s.io/kube-aggregator v0.22.4/go.mod h1:nH2L1wiG9pMqYV7P8XIMb9RbIEZPBwxz0iJqPPrtALU=
|
k8s.io/kube-aggregator v0.23.0/go.mod h1:b1vpoaTWKZjCzvbe1KXFw3vPbISrghJsg7/RI8oZUME=
|
||||||
k8s.io/kube-controller-manager v0.22.4/go.mod h1:BLoqqosh47s25JarHCC5ghmV24AlYp5/tRjatt/YjUY=
|
k8s.io/kube-controller-manager v0.23.0/go.mod h1:iHapRJJBe+fWu6hG3ye43YMFEeZcnIlRxDUS72bwJoE=
|
||||||
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
|
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
|
||||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80=
|
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4=
|
||||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
|
||||||
k8s.io/kube-proxy v0.22.4/go.mod h1:TTzZmcecSHXUL/3d6P4puVrZt4h0UNhT2RmxSdmg7B0=
|
k8s.io/kube-proxy v0.23.0/go.mod h1:AFPfNIiOeDhHVtfN7ZfE1Wd8aP5qYov3khPu4VFeBb4=
|
||||||
k8s.io/kube-scheduler v0.22.4/go.mod h1:2q5YGJngwFZ/9witl/n8Dij9qf52T3nR1g6OD6+pvLM=
|
k8s.io/kube-scheduler v0.23.0/go.mod h1:BXDjbJEXtr9PU5/XzLtWMNG6Mid4GYBSGVWzP72UxKk=
|
||||||
k8s.io/kubectl v0.22.4 h1:ECUO1QWyZ70DiIKEfgBx+8i9D98uspVOwgc1APs/07w=
|
k8s.io/kubectl v0.23.0 h1:WABWfj+Z4tC3SfKBCtZr5sIVHsFtkU9Azii4DR9IT6Y=
|
||||||
k8s.io/kubectl v0.22.4/go.mod h1:ok2qRT6y2Gy4+y+mniJVyUMKeBHP4OWS9Rdtf/QTM5I=
|
k8s.io/kubectl v0.23.0/go.mod h1:TfcGEs3u4dkmoC2eku1GYymdGaMtPMcaLLFrX/RB2kI=
|
||||||
k8s.io/kubelet v0.22.4 h1:0eaVDObhAuDCDnQJS9xqgfAP5/IWHMt6un4L/DQs0so=
|
k8s.io/kubelet v0.23.0 h1:hHdHe/Hp3R2HzxnYI8/f173gDUOTRYERd7S7+to9MZw=
|
||||||
k8s.io/kubelet v0.22.4/go.mod h1:9dCtyqqDnXJYF9E2mejBmDQb+flkAGFBzGgnlW/goyo=
|
k8s.io/kubelet v0.23.0/go.mod h1:A4DxfIt5Ka+rz54HAFhs1bgiFjJT6lcaAYUcACZl1/k=
|
||||||
k8s.io/kubernetes v1.22.4 h1:N5kU4bJEghcB2226/GH9Bca+oNcH6JTplcr9euN5ti8=
|
k8s.io/kubernetes v1.23.0 h1:r2DrryCpnmFfBuelpUNSWXHtD6Zy7SdwaCcycV5DsJE=
|
||||||
k8s.io/kubernetes v1.22.4/go.mod h1:cMy6DFG4E+/jxMgxw1aWMwZqvI1AueV3HCcG9S7QNIk=
|
k8s.io/kubernetes v1.23.0/go.mod h1:sgD3+Qzb8FHlRKlZnNCN+np3zZuHEAb/0PKLJkYyCUI=
|
||||||
k8s.io/legacy-cloud-providers v0.22.4/go.mod h1:Kw5X3DTa1/skHsKVgcrcK9d1JVXrdQpG77kWg/JPV68=
|
k8s.io/legacy-cloud-providers v0.23.0/go.mod h1:tM5owPlhLyEYJC2FLHgcGu1jks5ANvH2JlY03mnUYU4=
|
||||||
k8s.io/metrics v0.22.4/go.mod h1:6F/iwuYb1w2QDCoHkeMFLf4pwHBcYKLm4mPtVHKYrIw=
|
k8s.io/metrics v0.23.0/go.mod h1:NDiZTwppEtAuKJ1Rxt3S4dhyRzdp6yUcJf0vo023dPo=
|
||||||
k8s.io/mount-utils v0.22.4 h1:COkD8uKbphYVZXDYR4+464sZaeiYIwU5hdTyigjz0Xc=
|
k8s.io/mount-utils v0.23.0 h1:8sGMlbbQOA268SidZVoL7wOgEcbByoa6+bvFZCywhbg=
|
||||||
k8s.io/mount-utils v0.22.4/go.mod h1:dHl6c2P60T5LHUnZxVslyly9EDCMzvhtISO5aY+Z4sk=
|
k8s.io/mount-utils v0.23.0/go.mod h1:9pFhzVjxle1osJUo++9MFDat9HPkQUOoHCn+eExZ3Ew=
|
||||||
k8s.io/pod-security-admission v0.22.4/go.mod h1:R6VgmZm77Ik1qWRBBExuiUIRXR6kGQIRM/Zh5yVpYyA=
|
k8s.io/pod-security-admission v0.23.0/go.mod h1:vGExA081PHZFK9Yma4kuPtfWwy5zxbEUhniiUDKFicM=
|
||||||
k8s.io/sample-apiserver v0.22.4/go.mod h1:QIrXoUymVFpdy0Ei5WQjOa/Ewi3Ni+5XEhG8WD/D4iI=
|
k8s.io/sample-apiserver v0.23.0/go.mod h1:o0U/1hkfndbnLg1OfVHQiG08lmDkYJq7qljCuwjoTrI=
|
||||||
k8s.io/system-validators v1.5.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q=
|
k8s.io/system-validators v1.6.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q=
|
||||||
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g=
|
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs=
|
||||||
|
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
|
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
|
||||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
||||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||||
@ -1644,19 +1746,23 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
|
|||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22 h1:fmRfl9WJ4ApJn7LxNuED4m0t18qivVQOxP6aAYG9J6c=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25 h1:DEQ12ZRxJjsglk5JIi5bLgpKaHihGervKmg5uryaEHw=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25/go.mod h1:Mlj9PNLmG9bZ6BHFwFKDo5afkpWyUISkb9Me0GnK66I=
|
||||||
sigs.k8s.io/controller-runtime v0.2.2/go.mod h1:9dyohw3ZtoXQuV1e766PHUn+cmrRCIcBh6XIMFNMZ+I=
|
sigs.k8s.io/controller-runtime v0.2.2/go.mod h1:9dyohw3ZtoXQuV1e766PHUn+cmrRCIcBh6XIMFNMZ+I=
|
||||||
sigs.k8s.io/controller-runtime v0.10.3 h1:s5Ttmw/B4AuIbwrXD3sfBkXwnPMMWrqpVj4WRt1dano=
|
sigs.k8s.io/controller-runtime v0.11.0-beta.0.0.20211208212546-f236f0345ad2 h1:+ReKrjTrd57mtAU19BJkxSAaWRIQkFlaWcO6dGFVP1g=
|
||||||
sigs.k8s.io/controller-runtime v0.10.3/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY=
|
sigs.k8s.io/controller-runtime v0.11.0-beta.0.0.20211208212546-f236f0345ad2/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA=
|
||||||
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
|
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s=
|
||||||
sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs=
|
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=
|
||||||
sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go=
|
sigs.k8s.io/kustomize/api v0.10.1/go.mod h1:2FigT1QN6xKdcnGS2Ppp1uIWrtWN28Ms8A3OZUZhwr8=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM=
|
sigs.k8s.io/kustomize/cmd/config v0.10.2/go.mod h1:K2aW7nXJ0AaT+VA/eO0/dzFLxmpFcTzudmAgDwPY1HQ=
|
||||||
|
sigs.k8s.io/kustomize/kustomize/v4 v4.4.1/go.mod h1:qOKJMMz2mBP+vcS7vK+mNz4HBLjaQSWRY22EF6Tb7Io=
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.13.0/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLCK30D47m4E=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 h1:kDvPBbnPk+qYmkHmSo8vKGp438IASWofnbbUKDE/bv0=
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.0/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||||
sigs.k8s.io/testing_frameworks v0.1.1/go.mod h1:VVBKrHmJ6Ekkfz284YKhQePcdycOzNH9qL6ht1zEr/U=
|
sigs.k8s.io/testing_frameworks v0.1.1/go.mod h1:VVBKrHmJ6Ekkfz284YKhQePcdycOzNH9qL6ht1zEr/U=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
|
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||||
|
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||||
|
@ -149,7 +149,7 @@ func checkContentSource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateVolume creates a reservation and the volume in backend, if it is not already present.
|
// CreateVolume creates a reservation and the volume in backend, if it is not already present.
|
||||||
// nolint:gocyclo,cyclop // TODO: reduce complexity
|
// nolint:gocognit,gocyclo,nestif,cyclop // TODO: reduce complexity
|
||||||
func (cs *ControllerServer) CreateVolume(
|
func (cs *ControllerServer) CreateVolume(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
|
req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
|
||||||
@ -210,6 +210,31 @@ func (cs *ControllerServer) CreateVolume(
|
|||||||
// TODO return error message if requested vol size greater than found volume return error
|
// TODO return error message if requested vol size greater than found volume return error
|
||||||
|
|
||||||
if vID != nil {
|
if vID != nil {
|
||||||
|
if sID != nil || pvID != nil {
|
||||||
|
// while cloning the volume the size is not populated properly to the new volume now.
|
||||||
|
// it will be fixed in cephfs soon with the parentvolume size. Till then by below
|
||||||
|
// resize we are making sure we return or satisfy the requested size by setting the size
|
||||||
|
// explicitly
|
||||||
|
err = volOptions.ResizeVolume(ctx, fsutil.VolumeID(vID.FsSubvolName), volOptions.Size)
|
||||||
|
if err != nil {
|
||||||
|
purgeErr := volOptions.PurgeVolume(ctx, fsutil.VolumeID(vID.FsSubvolName), false)
|
||||||
|
if purgeErr != nil {
|
||||||
|
log.ErrorLog(ctx, "failed to delete volume %s: %v", requestName, purgeErr)
|
||||||
|
// All errors other than ErrVolumeNotFound should return an error back to the caller
|
||||||
|
if !errors.Is(purgeErr, cerrors.ErrVolumeNotFound) {
|
||||||
|
return nil, status.Error(codes.Internal, purgeErr.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errUndo := core.UndoVolReservation(ctx, volOptions, *vID, secret)
|
||||||
|
if errUndo != nil {
|
||||||
|
log.WarningLog(ctx, "failed undoing reservation of volume: %s (%s)",
|
||||||
|
requestName, errUndo)
|
||||||
|
}
|
||||||
|
log.ErrorLog(ctx, "failed to expand volume %s: %v", fsutil.VolumeID(vID.FsSubvolName), err)
|
||||||
|
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
volumeContext := req.GetParameters()
|
volumeContext := req.GetParameters()
|
||||||
volumeContext["subvolumeName"] = vID.FsSubvolName
|
volumeContext["subvolumeName"] = vID.FsSubvolName
|
||||||
volumeContext["subvolumePath"] = volOptions.RootPath
|
volumeContext["subvolumePath"] = volOptions.RootPath
|
||||||
|
@ -129,28 +129,6 @@ func checkStaticVolume(pv *corev1.PersistentVolume) bool {
|
|||||||
return pv.Spec.CSI.VolumeAttributes["staticVolume"] == "true"
|
return pv.Spec.CSI.VolumeAttributes["staticVolume"] == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
// storeVolumeIDInPV stores the new volumeID in PV object.
|
|
||||||
func (r ReconcilePersistentVolume) storeVolumeIDInPV(
|
|
||||||
ctx context.Context,
|
|
||||||
pv *corev1.PersistentVolume,
|
|
||||||
newVolumeID string) error {
|
|
||||||
if v, ok := pv.Annotations[rbd.PVVolumeHandleAnnotationKey]; ok {
|
|
||||||
if v == newVolumeID {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if pv.Annotations == nil {
|
|
||||||
pv.Annotations = make(map[string]string)
|
|
||||||
}
|
|
||||||
if pv.Labels == nil {
|
|
||||||
pv.Labels = make(map[string]string)
|
|
||||||
}
|
|
||||||
pv.Labels[rbd.PVReplicatedLabelKey] = rbd.PVReplicatedLabelValue
|
|
||||||
pv.Annotations[rbd.PVVolumeHandleAnnotationKey] = newVolumeID
|
|
||||||
|
|
||||||
return r.client.Update(ctx, pv)
|
|
||||||
}
|
|
||||||
|
|
||||||
// reconcilePV will extract the image details from the pv spec and regenerates
|
// reconcilePV will extract the image details from the pv spec and regenerates
|
||||||
// the omap data.
|
// the omap data.
|
||||||
func (r ReconcilePersistentVolume) reconcilePV(ctx context.Context, obj runtime.Object) error {
|
func (r ReconcilePersistentVolume) reconcilePV(ctx context.Context, obj runtime.Object) error {
|
||||||
@ -200,12 +178,7 @@ func (r ReconcilePersistentVolume) reconcilePV(ctx context.Context, obj runtime.
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if rbdVolID != volumeHandler {
|
if rbdVolID != volumeHandler {
|
||||||
err = r.storeVolumeIDInPV(ctx, pv, rbdVolID)
|
log.DebugLog(ctx, "volumeHandler changed from %s to %s", volumeHandler, rbdVolID)
|
||||||
if err != nil {
|
|
||||||
log.ErrorLogMsg("failed to store volumeID in PV %s", err)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -290,3 +290,19 @@ func requirePositive(x int64) int64 {
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsBlockMultiNode checks the volume capabilities for BlockMode and MultiNode.
|
||||||
|
func IsBlockMultiNode(caps []*csi.VolumeCapability) (bool, bool) {
|
||||||
|
isMultiNode := false
|
||||||
|
isBlock := false
|
||||||
|
for _, capability := range caps {
|
||||||
|
if capability.GetAccessMode().GetMode() == csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER {
|
||||||
|
isMultiNode = true
|
||||||
|
}
|
||||||
|
if capability.GetBlock() != nil {
|
||||||
|
isBlock = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isBlock, isMultiNode
|
||||||
|
}
|
||||||
|
@ -116,3 +116,64 @@ func TestRequirePositive(t *testing.T) {
|
|||||||
assert.Equal(t, requirePositive(-1), int64(0))
|
assert.Equal(t, requirePositive(-1), int64(0))
|
||||||
assert.Equal(t, requirePositive(1), int64(1))
|
assert.Equal(t, requirePositive(1), int64(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsBlockMultiNode(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
blockCap := &csi.VolumeCapability{
|
||||||
|
AccessType: &csi.VolumeCapability_Block{
|
||||||
|
Block: &csi.VolumeCapability_BlockVolume{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fsCap := &csi.VolumeCapability{
|
||||||
|
AccessType: &csi.VolumeCapability_Mount{
|
||||||
|
Mount: &csi.VolumeCapability_MountVolume{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
multiNodeCap := &csi.VolumeCapability{
|
||||||
|
AccessMode: &csi.VolumeCapability_AccessMode{
|
||||||
|
Mode: csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
singleNodeCap := &csi.VolumeCapability{
|
||||||
|
AccessMode: &csi.VolumeCapability_AccessMode{
|
||||||
|
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_MULTI_WRITER,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
caps []*csi.VolumeCapability
|
||||||
|
isBlock bool
|
||||||
|
isMultiNode bool
|
||||||
|
}{{
|
||||||
|
name: "block/multi-node",
|
||||||
|
caps: []*csi.VolumeCapability{blockCap, multiNodeCap},
|
||||||
|
isBlock: true,
|
||||||
|
isMultiNode: true,
|
||||||
|
}, {
|
||||||
|
name: "block/single-node",
|
||||||
|
caps: []*csi.VolumeCapability{blockCap, singleNodeCap},
|
||||||
|
isBlock: true,
|
||||||
|
isMultiNode: false,
|
||||||
|
}, {
|
||||||
|
name: "filesystem/multi-node",
|
||||||
|
caps: []*csi.VolumeCapability{fsCap, multiNodeCap},
|
||||||
|
isBlock: false,
|
||||||
|
isMultiNode: true,
|
||||||
|
}, {
|
||||||
|
name: "filesystem/single-node",
|
||||||
|
caps: []*csi.VolumeCapability{fsCap, singleNodeCap},
|
||||||
|
isBlock: false,
|
||||||
|
isMultiNode: false,
|
||||||
|
}}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
isBlock, isMultiNode := IsBlockMultiNode(test.caps)
|
||||||
|
assert.Equal(t, isBlock, test.isBlock, test.name)
|
||||||
|
assert.Equal(t, isMultiNode, test.isMultiNode, test.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
226
internal/kms/keyprotect.go
Normal file
226
internal/kms/keyprotect.go
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 The Ceph-CSI Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kms
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ceph/ceph-csi/internal/util/k8s"
|
||||||
|
|
||||||
|
kp "github.com/IBM/keyprotect-go-client"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
kmsTypeKeyProtectMetadata = "kp-metadata"
|
||||||
|
|
||||||
|
// keyProtectMetadataDefaultSecretsName is the default name of the Kubernetes Secret
|
||||||
|
// that contains the credentials to access the Key Protect KMS. The name of
|
||||||
|
// the Secret can be configured by setting the `KMS_SECRET_NAME`
|
||||||
|
// option.
|
||||||
|
//
|
||||||
|
// #nosec:G101, value not credential, just references token.
|
||||||
|
keyProtectMetadataDefaultSecretsName = "ceph-csi-kp-credentials"
|
||||||
|
|
||||||
|
// keyProtectSecretNameKey contains the name of the Kubernetes Secret that has
|
||||||
|
// the credentials to access the Key ProtectKMS.
|
||||||
|
//
|
||||||
|
// #nosec:G101, no hardcoded secret, this is a configuration key.
|
||||||
|
keyProtectSecretNameKey = "KMS_SECRET_NAME"
|
||||||
|
keyProtectRegionKey = "KP_REGION"
|
||||||
|
|
||||||
|
keyProtectServiceInstanceID = "KP_SERVICE_INSTANCE_ID"
|
||||||
|
// The following options are part of the Kubernetes Secrets.
|
||||||
|
// #nosec:G101, no hardcoded secrets, only configuration keys.
|
||||||
|
keyProtectServiceAPIKey = "KP_SERVICE_API_KEY"
|
||||||
|
KeyProtectCustomerRootKey = "KP_CUSTOMER_ROOT_KEY"
|
||||||
|
|
||||||
|
keyProtectSessionToken = "KP_SESSION_TOKEN"
|
||||||
|
keyProtectCRK = "KP_CRK_ARN"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = RegisterProvider(Provider{
|
||||||
|
UniqueID: kmsTypeKeyProtectMetadata,
|
||||||
|
Initializer: initKeyProtectKMS,
|
||||||
|
})
|
||||||
|
|
||||||
|
// KeyProtectKMS store the KMS connection information retrieved from the kms configmap.
|
||||||
|
type KeyProtectKMS struct {
|
||||||
|
// basic options to get the secret
|
||||||
|
namespace string
|
||||||
|
secretName string
|
||||||
|
|
||||||
|
// standard KeyProtect configuration options
|
||||||
|
client *kp.Client
|
||||||
|
serviceAPIKey string
|
||||||
|
customerRootKey string
|
||||||
|
serviceInstanceID string
|
||||||
|
region string
|
||||||
|
sessionToken string
|
||||||
|
crk string
|
||||||
|
}
|
||||||
|
|
||||||
|
func initKeyProtectKMS(args ProviderInitArgs) (EncryptionKMS, error) {
|
||||||
|
kms := &KeyProtectKMS{
|
||||||
|
namespace: args.Namespace,
|
||||||
|
}
|
||||||
|
// required options for further configuration (getting secrets)
|
||||||
|
err := setConfigString(&kms.secretName, args.Config, keyProtectSecretNameKey)
|
||||||
|
if errors.Is(err, errConfigOptionInvalid) {
|
||||||
|
return nil, err
|
||||||
|
} else if errors.Is(err, errConfigOptionMissing) {
|
||||||
|
kms.secretName = keyProtectMetadataDefaultSecretsName
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setConfigString(&kms.serviceInstanceID, args.Config, keyProtectServiceInstanceID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the Kubernetes Secret with credentials
|
||||||
|
secrets, err := kms.getSecrets()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get secrets for %T: %w", kms,
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setConfigString(&kms.serviceAPIKey, secrets, keyProtectServiceAPIKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = setConfigString(&kms.customerRootKey, secrets, KeyProtectCustomerRootKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// keyProtectSessionToken is optional
|
||||||
|
err = setConfigString(&kms.sessionToken, secrets, keyProtectSessionToken)
|
||||||
|
if errors.Is(err, errConfigOptionInvalid) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyProtect Region is optional
|
||||||
|
err = setConfigString(&kms.region, args.Config, keyProtectRegionKey)
|
||||||
|
if errors.Is(err, errConfigOptionInvalid) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// crk arn is optional
|
||||||
|
err = setConfigString(&kms.crk, secrets, keyProtectCRK)
|
||||||
|
if errors.Is(err, errConfigOptionInvalid) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return kms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kms *KeyProtectKMS) getSecrets() (map[string]interface{}, error) {
|
||||||
|
c, err := k8s.NewK8sClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to connect to Kubernetes to "+
|
||||||
|
"get Secret %s/%s: %w", kms.namespace, kms.secretName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
secret, err := c.CoreV1().Secrets(kms.namespace).Get(context.TODO(),
|
||||||
|
kms.secretName, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get Secret %s/%s: %w",
|
||||||
|
kms.namespace, kms.secretName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config := make(map[string]interface{})
|
||||||
|
|
||||||
|
for k, v := range secret.Data {
|
||||||
|
switch k {
|
||||||
|
case keyProtectServiceAPIKey, KeyProtectCustomerRootKey, keyProtectSessionToken, keyProtectCRK:
|
||||||
|
config[k] = string(v)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported option for KMS "+
|
||||||
|
"provider %q: %s", kmsTypeKeyProtectMetadata, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kms *KeyProtectKMS) Destroy() {
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kms *KeyProtectKMS) RequiresDEKStore() DEKStoreType {
|
||||||
|
return DEKStoreMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kms *KeyProtectKMS) getService() error {
|
||||||
|
// Use your Service API Key and your KeyProtect Service Instance ID to create a ClientConfig
|
||||||
|
cc := kp.ClientConfig{
|
||||||
|
BaseURL: kp.DefaultBaseURL,
|
||||||
|
APIKey: kms.serviceAPIKey,
|
||||||
|
InstanceID: kms.serviceInstanceID,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a new client from the config
|
||||||
|
client, err := kp.New(cc, kp.DefaultTransport())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create keyprotect client: %w", err)
|
||||||
|
}
|
||||||
|
kms.client = client
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptDEK uses the KeyProtect KMS and the configured CRK to encrypt the DEK.
|
||||||
|
func (kms *KeyProtectKMS) EncryptDEK(volumeID, plainDEK string) (string, error) {
|
||||||
|
if err := kms.getService(); err != nil {
|
||||||
|
return "", fmt.Errorf("could not get KMS service: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dekByteSlice := []byte(plainDEK)
|
||||||
|
aadVolID := []string{volumeID}
|
||||||
|
result, err := kms.client.Wrap(context.TODO(), kms.customerRootKey, dekByteSlice, &aadVolID)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to wrap the DEK: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// base64 encode the encrypted DEK, so that storing it should not have
|
||||||
|
// issues
|
||||||
|
|
||||||
|
return base64.StdEncoding.EncodeToString(result), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecryptDEK uses the Key protect KMS and the configured CRK to decrypt the DEK.
|
||||||
|
func (kms *KeyProtectKMS) DecryptDEK(volumeID, encryptedDEK string) (string, error) {
|
||||||
|
if err := kms.getService(); err != nil {
|
||||||
|
return "", fmt.Errorf("could not get KMS service: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ciphertextBlob, err := base64.StdEncoding.DecodeString(encryptedDEK)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to decode base64 cipher: %w",
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := kms.client.Unwrap(context.TODO(), kms.customerRootKey, ciphertextBlob, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to unwrap the DEK: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(result), nil
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
// +build go1.14
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2020 The Kubernetes Authors.
|
Copyright 2021 The Ceph-CSI Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -16,14 +14,16 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package flag
|
package kms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func TestKeyProtectMetadataKMSRegistered(t *testing.T) {
|
||||||
// support official IANA names as well on go1.14
|
t.Parallel()
|
||||||
ciphers["TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"] = tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
_, ok := kmsManager.providers[kmsTypeKeyProtectMetadata]
|
||||||
ciphers["TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"] = tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
assert.True(t, ok)
|
||||||
}
|
}
|
@ -94,22 +94,15 @@ func (cs *ControllerServer) validateVolumeReq(ctx context.Context, req *csi.Crea
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseVolCreateRequest take create volume `request` argument and make use of the
|
||||||
|
// request arguments for subsequent calls.
|
||||||
func (cs *ControllerServer) parseVolCreateRequest(
|
func (cs *ControllerServer) parseVolCreateRequest(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *csi.CreateVolumeRequest) (*rbdVolume, error) {
|
req *csi.CreateVolumeRequest) (*rbdVolume, error) {
|
||||||
// TODO (sbezverk) Last check for not exceeding total storage capacity
|
// TODO (sbezverk) Last check for not exceeding total storage capacity
|
||||||
|
|
||||||
isMultiNode := false
|
// RO modes need to be handled independently (ie right now even if access mode is RO, they'll be RW upon attach)
|
||||||
isBlock := false
|
isBlock, isMultiNode := csicommon.IsBlockMultiNode(req.VolumeCapabilities)
|
||||||
for _, capability := range req.VolumeCapabilities {
|
|
||||||
// RO modes need to be handled independently (ie right now even if access mode is RO, they'll be RW upon attach)
|
|
||||||
if capability.GetAccessMode().GetMode() == csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER {
|
|
||||||
isMultiNode = true
|
|
||||||
}
|
|
||||||
if capability.GetBlock() != nil {
|
|
||||||
isBlock = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to fail early if the user is trying to create a RWX on a non-block type device
|
// We want to fail early if the user is trying to create a RWX on a non-block type device
|
||||||
if isMultiNode && !isBlock {
|
if isMultiNode && !isBlock {
|
||||||
@ -271,18 +264,19 @@ func checkValidCreateVolumeRequest(rbdVol, parentVol *rbdVolume, rbdSnap *rbdSna
|
|||||||
func (cs *ControllerServer) CreateVolume(
|
func (cs *ControllerServer) CreateVolume(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
|
req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
|
||||||
if err := cs.validateVolumeReq(ctx, req); err != nil {
|
err := cs.validateVolumeReq(ctx, req)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: create/get a connection from the the ConnPool, and do not pass
|
// TODO: create/get a connection from the the ConnPool, and do not pass
|
||||||
// the credentials to any of the utility functions.
|
// the credentials to any of the utility functions.
|
||||||
cr, err := util.NewUserCredentials(req.GetSecrets())
|
|
||||||
|
cr, err := util.NewUserCredentialsWithMigration(req.GetSecrets())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
defer cr.DeleteCredentials()
|
defer cr.DeleteCredentials()
|
||||||
|
|
||||||
rbdVol, err := cs.parseVolCreateRequest(ctx, req)
|
rbdVol, err := cs.parseVolCreateRequest(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -391,7 +385,6 @@ func (cs *ControllerServer) repairExistingVolume(ctx context.Context, req *csi.C
|
|||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rbdVol is a restore from snapshot, rbdSnap is passed
|
// rbdVol is a restore from snapshot, rbdSnap is passed
|
||||||
case vcs.GetSnapshot() != nil:
|
case vcs.GetSnapshot() != nil:
|
||||||
// When restoring of a thick-provisioned volume was happening,
|
// When restoring of a thick-provisioned volume was happening,
|
||||||
@ -822,17 +815,9 @@ func (cs *ControllerServer) DeleteVolume(
|
|||||||
return nil, status.Error(codes.InvalidArgument, "empty volume ID in request")
|
return nil, status.Error(codes.InvalidArgument, "empty volume ID in request")
|
||||||
}
|
}
|
||||||
|
|
||||||
secrets := req.GetSecrets()
|
cr, err := util.NewUserCredentialsWithMigration(req.GetSecrets())
|
||||||
if util.IsMigrationSecret(secrets) {
|
|
||||||
secrets, err = util.ParseAndSetSecretMapFromMigSecret(secrets)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cr, err := util.NewUserCredentials(secrets)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
defer cr.DeleteCredentials()
|
defer cr.DeleteCredentials()
|
||||||
|
|
||||||
@ -865,7 +850,7 @@ func (cs *ControllerServer) DeleteVolume(
|
|||||||
return &csi.DeleteVolumeResponse{}, nil
|
return &csi.DeleteVolumeResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rbdVol, err := GenVolFromVolID(ctx, volumeID, cr, secrets)
|
rbdVol, err := GenVolFromVolID(ctx, volumeID, cr, req.GetSecrets())
|
||||||
defer rbdVol.Destroy()
|
defer rbdVol.Destroy()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cs.checkErrAndUndoReserve(ctx, err, volumeID, rbdVol, cr)
|
return cs.checkErrAndUndoReserve(ctx, err, volumeID, rbdVol, cr)
|
||||||
@ -1432,7 +1417,8 @@ func (cs *ControllerServer) DeleteSnapshot(
|
|||||||
func (cs *ControllerServer) ControllerExpandVolume(
|
func (cs *ControllerServer) ControllerExpandVolume(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) {
|
req *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) {
|
||||||
if err := cs.Driver.ValidateControllerServiceRequest(csi.ControllerServiceCapability_RPC_EXPAND_VOLUME); err != nil {
|
err := cs.Driver.ValidateControllerServiceRequest(csi.ControllerServiceCapability_RPC_EXPAND_VOLUME)
|
||||||
|
if err != nil {
|
||||||
log.ErrorLog(ctx, "invalid expand volume req: %v", protosanitizer.StripSecrets(req))
|
log.ErrorLog(ctx, "invalid expand volume req: %v", protosanitizer.StripSecrets(req))
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1456,9 +1442,9 @@ func (cs *ControllerServer) ControllerExpandVolume(
|
|||||||
}
|
}
|
||||||
defer cs.VolumeLocks.Release(volID)
|
defer cs.VolumeLocks.Release(volID)
|
||||||
|
|
||||||
cr, err := util.NewUserCredentials(req.GetSecrets())
|
cr, err := util.NewUserCredentialsWithMigration(req.GetSecrets())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
defer cr.DeleteCredentials()
|
defer cr.DeleteCredentials()
|
||||||
|
|
||||||
|
@ -270,19 +270,11 @@ func (ns *NodeServer) NodeStageVolume(
|
|||||||
}
|
}
|
||||||
|
|
||||||
volID := req.GetVolumeId()
|
volID := req.GetVolumeId()
|
||||||
secrets := req.GetSecrets()
|
cr, err := util.NewUserCredentialsWithMigration(req.GetSecrets())
|
||||||
if util.IsMigrationSecret(secrets) {
|
|
||||||
secrets, err = util.ParseAndSetSecretMapFromMigSecret(secrets)
|
|
||||||
if err != nil {
|
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cr, err := util.NewUserCredentials(secrets)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
defer cr.DeleteCredentials()
|
defer cr.DeleteCredentials()
|
||||||
|
|
||||||
if acquired := ns.VolumeLocks.TryAcquire(volID); !acquired {
|
if acquired := ns.VolumeLocks.TryAcquire(volID); !acquired {
|
||||||
log.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volID)
|
log.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volID)
|
||||||
|
|
||||||
@ -315,7 +307,7 @@ func (ns *NodeServer) NodeStageVolume(
|
|||||||
return nil, status.Error(codes.InvalidArgument, "missing required parameter imageFeatures")
|
return nil, status.Error(codes.InvalidArgument, "missing required parameter imageFeatures")
|
||||||
}
|
}
|
||||||
|
|
||||||
rv, err := populateRbdVol(ctx, req, cr, secrets)
|
rv, err := populateRbdVol(ctx, req, cr, req.GetSecrets())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,6 @@ import (
|
|||||||
"github.com/ceph/ceph-csi/internal/util/log"
|
"github.com/ceph/ceph-csi/internal/util/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// PVVolumeHandleAnnotationKey is the annotation key set on the PV object.
|
|
||||||
PVVolumeHandleAnnotationKey = "csi.ceph.io/volume-handle"
|
|
||||||
// PVReplicatedLabelKey is the label key set on PV object.
|
|
||||||
PVReplicatedLabelKey = "csi.ceph.io/replicated-volume"
|
|
||||||
// PVReplicatedLabelValue is the label value set on PV object.
|
|
||||||
PVReplicatedLabelValue = "volume-handle-detected"
|
|
||||||
)
|
|
||||||
|
|
||||||
func validateNonEmptyField(field, fieldName, structName string) error {
|
func validateNonEmptyField(field, fieldName, structName string) error {
|
||||||
if field == "" {
|
if field == "" {
|
||||||
return fmt.Errorf("value '%s' in '%s' structure cannot be empty", fieldName, structName)
|
return fmt.Errorf("value '%s' in '%s' structure cannot be empty", fieldName, structName)
|
||||||
|
@ -29,7 +29,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ceph/ceph-csi/internal/util"
|
"github.com/ceph/ceph-csi/internal/util"
|
||||||
"github.com/ceph/ceph-csi/internal/util/k8s"
|
|
||||||
"github.com/ceph/ceph-csi/internal/util/log"
|
"github.com/ceph/ceph-csi/internal/util/log"
|
||||||
|
|
||||||
"github.com/ceph/go-ceph/rados"
|
"github.com/ceph/go-ceph/rados"
|
||||||
@ -38,7 +37,6 @@ import (
|
|||||||
"github.com/container-storage-interface/spec/lib/go/csi"
|
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
"github.com/golang/protobuf/ptypes"
|
"github.com/golang/protobuf/ptypes"
|
||||||
"github.com/golang/protobuf/ptypes/timestamp"
|
"github.com/golang/protobuf/ptypes/timestamp"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/cloud-provider/volume/helpers"
|
"k8s.io/cloud-provider/volume/helpers"
|
||||||
mount "k8s.io/mount-utils"
|
mount "k8s.io/mount-utils"
|
||||||
@ -1179,40 +1177,6 @@ func GenVolFromVolID(
|
|||||||
return rbdVol, vErr
|
return rbdVol, vErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: remove extracting volumeID from PV annotations.
|
|
||||||
|
|
||||||
// If the volume details are not found in the OMAP it can be a mirrored RBD
|
|
||||||
// image and the OMAP is already generated and the volumeHandle might not
|
|
||||||
// be the same in the PV.Spec.CSI.VolumeHandle. Check the PV annotation for
|
|
||||||
// the new volumeHandle. If the new volumeHandle is found, generate the RBD
|
|
||||||
// volume structure from the new volumeHandle.
|
|
||||||
c, cErr := k8s.NewK8sClient()
|
|
||||||
if cErr != nil {
|
|
||||||
return vol, cErr
|
|
||||||
}
|
|
||||||
|
|
||||||
listOpt := metav1.ListOptions{
|
|
||||||
LabelSelector: PVReplicatedLabelKey,
|
|
||||||
}
|
|
||||||
pvlist, pErr := c.CoreV1().PersistentVolumes().List(context.TODO(), listOpt)
|
|
||||||
if pErr != nil {
|
|
||||||
return vol, pErr
|
|
||||||
}
|
|
||||||
for i := range pvlist.Items {
|
|
||||||
if pvlist.Items[i].Spec.CSI != nil && pvlist.Items[i].Spec.CSI.VolumeHandle == volumeID {
|
|
||||||
if v, ok := pvlist.Items[i].Annotations[PVVolumeHandleAnnotationKey]; ok {
|
|
||||||
log.UsefulLog(ctx, "found new volumeID %s for existing volumeID %s", v, volumeID)
|
|
||||||
err = vi.DecomposeCSIID(v)
|
|
||||||
if err != nil {
|
|
||||||
return vol, fmt.Errorf("%w: error decoding volume ID (%s) (%s)",
|
|
||||||
ErrInvalidVolID, err, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return generateVolumeFromVolumeID(ctx, v, vi, cr, secrets)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vol, err
|
return vol, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,6 +314,9 @@ func createDummyImage(ctx context.Context, rbdVol *rbdVolume) error {
|
|||||||
}
|
}
|
||||||
dummyVol := *rbdVol
|
dummyVol := *rbdVol
|
||||||
dummyVol.RbdImageName = imgName
|
dummyVol.RbdImageName = imgName
|
||||||
|
// dummyVol holds rbdVol details, reset ImageID or else dummy image cannot be
|
||||||
|
// deleted from trash during repair operation.
|
||||||
|
dummyVol.ImageID = ""
|
||||||
f := []string{
|
f := []string{
|
||||||
librbd.FeatureNameLayering,
|
librbd.FeatureNameLayering,
|
||||||
librbd.FeatureNameObjectMap,
|
librbd.FeatureNameObjectMap,
|
||||||
|
@ -128,7 +128,7 @@ func GetMonValFromSecret(secrets map[string]string) (string, error) {
|
|||||||
func ParseAndSetSecretMapFromMigSecret(secretmap map[string]string) (map[string]string, error) {
|
func ParseAndSetSecretMapFromMigSecret(secretmap map[string]string) (map[string]string, error) {
|
||||||
newSecretMap := make(map[string]string)
|
newSecretMap := make(map[string]string)
|
||||||
// parse and set userKey
|
// parse and set userKey
|
||||||
if !IsMigrationSecret(secretmap) {
|
if !isMigrationSecret(secretmap) {
|
||||||
return nil, errors.New("passed secret map does not contain user key or it is nil")
|
return nil, errors.New("passed secret map does not contain user key or it is nil")
|
||||||
}
|
}
|
||||||
newSecretMap[credUserKey] = secretmap[migUserKey]
|
newSecretMap[credUserKey] = secretmap[migUserKey]
|
||||||
@ -141,15 +141,35 @@ func ParseAndSetSecretMapFromMigSecret(secretmap map[string]string) (map[string]
|
|||||||
return newSecretMap, nil
|
return newSecretMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMigrationSecret validates if the passed in secretmap is a secret
|
// isMigrationSecret validates if the passed in secretmap is a secret
|
||||||
// of a migration volume request. The migration secret carry a field
|
// of a migration volume request. The migration secret carry a field
|
||||||
// called `key` which is the equivalent of `userKey` which is what we
|
// called `key` which is the equivalent of `userKey` which is what we
|
||||||
// check here for identifying the secret.
|
// check here for identifying the secret.
|
||||||
func IsMigrationSecret(passedSecretMap map[string]string) bool {
|
func isMigrationSecret(secrets map[string]string) bool {
|
||||||
// the below 'nil' check is an extra measure as the request validators like
|
// the below 'nil' check is an extra measure as the request validators like
|
||||||
// ValidateNodeStageVolumeRequest() already does the nil check, however considering
|
// ValidateNodeStageVolumeRequest() already does the nil check, however considering
|
||||||
// this function can be called independently with a map of secret values
|
// this function can be called independently with a map of secret values
|
||||||
// it is good to have this check in place, also it gives clear error about this
|
// it is good to have this check in place, also it gives clear error about this
|
||||||
// was hit on migration request compared to general one.
|
// was hit on migration request compared to general one.
|
||||||
return len(passedSecretMap) != 0 && passedSecretMap[migUserKey] != ""
|
return len(secrets) != 0 && secrets[migUserKey] != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUserCredentialsWithMigration takes secret map from the request and validate it is
|
||||||
|
// a migration secret, if yes, it continues to create CR from it after parsing the migration
|
||||||
|
// secret. If it is not a migration it will continue the attempt to create credentials from it
|
||||||
|
// without parsing the secret. This function returns credentials and error.
|
||||||
|
func NewUserCredentialsWithMigration(secrets map[string]string) (*Credentials, error) {
|
||||||
|
if isMigrationSecret(secrets) {
|
||||||
|
migSecret, err := ParseAndSetSecretMapFromMigSecret(secrets)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
secrets = migSecret
|
||||||
|
}
|
||||||
|
cr, cErr := NewUserCredentials(secrets)
|
||||||
|
if cErr != nil {
|
||||||
|
return nil, cErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return cr, nil
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ func TestIsMigrationSecret(t *testing.T) {
|
|||||||
newtt := tt
|
newtt := tt
|
||||||
t.Run(newtt.name, func(t *testing.T) {
|
t.Run(newtt.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
if got := IsMigrationSecret(newtt.vc); got != newtt.want {
|
if got := isMigrationSecret(newtt.vc); got != newtt.want {
|
||||||
t.Errorf("isMigrationSecret() = %v, want %v", got, newtt.want)
|
t.Errorf("isMigrationSecret() = %v, want %v", got, newtt.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -2,6 +2,7 @@ ARG BASE_IMAGE
|
|||||||
FROM ${BASE_IMAGE}
|
FROM ${BASE_IMAGE}
|
||||||
|
|
||||||
ARG GOROOT=/usr/local/go
|
ARG GOROOT=/usr/local/go
|
||||||
|
ARG GOARCH
|
||||||
|
|
||||||
ENV GOPATH=/go \
|
ENV GOPATH=/go \
|
||||||
GOROOT=${GOROOT} \
|
GOROOT=${GOROOT} \
|
||||||
@ -11,8 +12,10 @@ ENV GOPATH=/go \
|
|||||||
COPY build.env /
|
COPY build.env /
|
||||||
|
|
||||||
RUN source /build.env \
|
RUN source /build.env \
|
||||||
|
&& \
|
||||||
|
( test -n "${GOARCH}" && exit 0; echo -e "\n\nMissing GOARCH argument for building image, install Golang or run: make containerized-build GOARCH=amd64\n\n"; exit 1 ) \
|
||||||
&& mkdir -p /usr/local/go \
|
&& mkdir -p /usr/local/go \
|
||||||
&& curl https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-amd64.tar.gz | tar xzf - -C ${GOROOT} --strip-components=1
|
&& curl https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-${GOARCH}.tar.gz | tar xzf - -C ${GOROOT} --strip-components=1
|
||||||
|
|
||||||
RUN dnf -y install \
|
RUN dnf -y install \
|
||||||
git \
|
git \
|
||||||
|
@ -11,33 +11,41 @@
|
|||||||
FROM registry.fedoraproject.org/fedora:latest
|
FROM registry.fedoraproject.org/fedora:latest
|
||||||
|
|
||||||
ARG GOPATH=/go
|
ARG GOPATH=/go
|
||||||
|
ARG GOROOT=/usr/local/go
|
||||||
|
ARG GOARCH
|
||||||
|
|
||||||
ENV \
|
ENV \
|
||||||
GOPATH=${GOPATH} \
|
GOPATH=${GOPATH} \
|
||||||
|
GOROOT=${GOROOT} \
|
||||||
GO111MODULE=on \
|
GO111MODULE=on \
|
||||||
PATH="${GOPATH}/bin:/opt/commitlint/node_modules/.bin:${PATH}"
|
PATH="${GOPATH}/bin:${GOROOT}/bin:/opt/commitlint/node_modules/.bin:${PATH}"
|
||||||
|
|
||||||
COPY build.env /
|
COPY build.env /
|
||||||
|
|
||||||
RUN source /build.env \
|
RUN source /build.env \
|
||||||
|
&& \
|
||||||
|
( test -n "${GOARCH}" && exit 0; echo -e "\n\nMissing GOARCH argument for building image, install Golang or run: make containerized-test GOARCH=amd64\n\n"; exit 1 ) \
|
||||||
&& dnf -y install \
|
&& dnf -y install \
|
||||||
git \
|
git \
|
||||||
make \
|
make \
|
||||||
golang \
|
|
||||||
gcc \
|
gcc \
|
||||||
|
findutils \
|
||||||
librados-devel \
|
librados-devel \
|
||||||
librbd-devel \
|
librbd-devel \
|
||||||
rubygems \
|
rubygems \
|
||||||
ShellCheck \
|
ShellCheck \
|
||||||
codespell \
|
codespell \
|
||||||
yamllint \
|
yamllint \
|
||||||
npm \
|
npm \
|
||||||
diffutils \
|
diffutils \
|
||||||
python3-prettytable \
|
python3-prettytable \
|
||||||
pylint \
|
pylint \
|
||||||
&& dnf -y update \
|
&& dnf -y update \
|
||||||
&& dnf -y clean all \
|
&& dnf -y clean all \
|
||||||
&& gem install mdl \
|
&& gem install mdl \
|
||||||
|
&& mkdir -p ${GOROOT} \
|
||||||
|
&& curl https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-${GOARCH}.tar.gz \
|
||||||
|
| tar xzf - -C ${GOROOT} --strip-components=1 \
|
||||||
&& curl -sf "https://install.goreleaser.com/github.com/golangci/golangci-lint.sh" \
|
&& curl -sf "https://install.goreleaser.com/github.com/golangci/golangci-lint.sh" \
|
||||||
| bash -s -- -b ${GOPATH}/bin "${GOLANGCI_VERSION}" \
|
| bash -s -- -b ${GOPATH}/bin "${GOLANGCI_VERSION}" \
|
||||||
&& curl -L https://git.io/get_helm.sh | bash -s -- --version "${HELM_VERSION}" \
|
&& curl -L https://git.io/get_helm.sh | bash -s -- --version "${HELM_VERSION}" \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[codespell]
|
[codespell]
|
||||||
# TODO: enable codespell on retest folder except vendor
|
# TODO: enable codespell on retest folder except vendor
|
||||||
skip = .git,./vendor,./docs/design/proposals/images,./actions/retest/*
|
skip = .git,./vendor,./docs/design/proposals/images,./actions/retest/*,go.sum
|
||||||
ignore-words-list = ExtraVersion,extraversion,ba
|
ignore-words-list = ExtraVersion,extraversion,ba
|
||||||
check-filenames = true
|
check-filenames = true
|
||||||
|
@ -3,7 +3,7 @@ all
|
|||||||
#Refer below url for more information about the markdown rules.
|
#Refer below url for more information about the markdown rules.
|
||||||
#https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md
|
#https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md
|
||||||
|
|
||||||
rule 'MD013', :code_blocks => false, :tables => false
|
rule 'MD013', :code_blocks => false, :tables => false, :line_length => 80
|
||||||
|
|
||||||
exclude_rule 'MD033' # In-line HTML: GitHub style markdown adds HTML tags
|
exclude_rule 'MD033' # In-line HTML: GitHub style markdown adds HTML tags
|
||||||
exclude_rule 'MD040' # Fenced code blocks should have a language specified
|
exclude_rule 'MD040' # Fenced code blocks should have a language specified
|
||||||
|
44
vendor/github.com/IBM/keyprotect-go-client/.gitignore
generated
vendored
Normal file
44
vendor/github.com/IBM/keyprotect-go-client/.gitignore
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
vendor
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
cover.*
|
||||||
|
|
||||||
|
# Eclipse
|
||||||
|
.project
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
.vscode
|
||||||
|
/*.covtmp
|
||||||
|
**/coverage
|
||||||
|
**/coverage.htmlvendor
|
||||||
|
**/coverage.txt
|
||||||
|
**/coverage.html
|
||||||
|
**/cover.html
|
||||||
|
**/coverage.out
|
||||||
|
**/coverage.tmp
|
||||||
|
*.coverprofile
|
25
vendor/github.com/IBM/keyprotect-go-client/.travis.yml
generated
vendored
Normal file
25
vendor/github.com/IBM/keyprotect-go-client/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
language: go
|
||||||
|
dist: xenial
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.14.x
|
||||||
|
- 1.15.x
|
||||||
|
|
||||||
|
env:
|
||||||
|
- GO111MODULE=on
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- GO111MODULE=off go get -u github.com/haya14busa/goverage
|
||||||
|
|
||||||
|
install:
|
||||||
|
- go build ./...
|
||||||
|
|
||||||
|
script:
|
||||||
|
- $GOPATH/bin/goverage -v -race -coverprofile=cover.out $(go list ./... | grep -v '/vendor|/scripts')
|
||||||
|
- go tool cover -func=cover.out
|
||||||
|
- go tool cover -html=cover.out -o=cover.html
|
||||||
|
|
||||||
|
# FIXME: these scripts don't exist in this repo
|
||||||
|
# after_success:
|
||||||
|
# - ./scripts/calculateCoverage.sh
|
||||||
|
# - ./scripts/publishCoverage.sh
|
49
vendor/github.com/IBM/keyprotect-go-client/CONTRIBUTING.md
generated
vendored
Normal file
49
vendor/github.com/IBM/keyprotect-go-client/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Contributing to keyprotect-go-client
|
||||||
|
|
||||||
|
`keyprotect-go-client` is open for code perusal and contributions. We welcome contributions in the form of feedback, bugs, or patches.
|
||||||
|
|
||||||
|
## Bugs and Feature Requests
|
||||||
|
|
||||||
|
If you find something that does not work as expected or would like to see a new feature added,
|
||||||
|
please open a [Github Issue](https://github.com/IBM/keyprotect-go-client/issues)
|
||||||
|
|
||||||
|
## Pull Requests
|
||||||
|
|
||||||
|
For your pull request to be merged, it must meet the criteria of a "correct patch", and also
|
||||||
|
be fully reviewed and approved by two Maintainer level contributors.
|
||||||
|
|
||||||
|
A correct patch is defined as the following:
|
||||||
|
|
||||||
|
- If the patch fixes a bug, it must be the simplest way to fix the issue
|
||||||
|
- Your patch must come with unit tests
|
||||||
|
- Unit tests (CI job) must pass
|
||||||
|
- New feature function should have integration tests as well
|
||||||
|
|
||||||
|
|
||||||
|
# Development
|
||||||
|
|
||||||
|
## Compiling the package
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go build ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
The client relies on go modules to pull in required dependencies at build time.
|
||||||
|
|
||||||
|
https://github.com/golang/go/wiki/Modules#how-to-use-modules
|
||||||
|
|
||||||
|
## Running the test cases
|
||||||
|
|
||||||
|
Using `go test`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test -v -race ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
The test cases are also runnable through `make`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make test
|
||||||
|
# or
|
||||||
|
make test-integration
|
||||||
|
```
|
201
vendor/github.com/IBM/keyprotect-go-client/LICENSE
generated
vendored
Normal file
201
vendor/github.com/IBM/keyprotect-go-client/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
8
vendor/github.com/IBM/keyprotect-go-client/Makefile
generated
vendored
Normal file
8
vendor/github.com/IBM/keyprotect-go-client/Makefile
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
.PHONY: test test-integration
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test -v -race ./...
|
||||||
|
|
||||||
|
test-integration:
|
||||||
|
go test -v -tags=integration ./...
|
173
vendor/github.com/IBM/keyprotect-go-client/README.md
generated
vendored
Normal file
173
vendor/github.com/IBM/keyprotect-go-client/README.md
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
# keyprotect-go-client
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.com/IBM/keyprotect-go-client.svg?branch=master)](https://travis-ci.com/IBM/keyprotect-go-client)
|
||||||
|
[![GoDoc](https://godoc.org/github.com/keyprotect-go-client?status.svg)](https://godoc.org/github.com/IBM/keyprotect-go-client)
|
||||||
|
|
||||||
|
keyprotect-go-client is a Go client library for interacting with the IBM KeyProtect service.
|
||||||
|
|
||||||
|
* [Questions / Support](#questions--support)
|
||||||
|
* [Usage](#usage)
|
||||||
|
* [Migrating](#migrating)
|
||||||
|
* [Authentication](#authentication)
|
||||||
|
* [Finding Instance UUIDs](#finding-a-keyprotect-service-instances-uuid)
|
||||||
|
* [Examples](#examples)
|
||||||
|
* [Contributing](/CONTRIBUTING.md)
|
||||||
|
|
||||||
|
## Questions / Support
|
||||||
|
|
||||||
|
There are many channels for asking questions about KeyProtect and this client.
|
||||||
|
|
||||||
|
- Ask a question on Stackoverflow and tag it with `key-protect` and `ibm-cloud`
|
||||||
|
- Open a [Github Issue](https://github.com/IBM/keyprotect-go-client/issues)
|
||||||
|
- If you work at IBM and have access to the internal Slack, you can join the `#key-protect` channel and ask there.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
This client expects that you have an existing IBM Cloud Key Protect Service Instance. To get started, visit the [IBM KeyProtect Catalog Page](https://cloud.ibm.com/catalog/services/key-protect).
|
||||||
|
|
||||||
|
Build a client with `ClientConfig` and `New`, then use the client to do some operations.
|
||||||
|
```go
|
||||||
|
import "github.com/IBM/keyprotect-go-client"
|
||||||
|
|
||||||
|
// Use your IAM API Key and your KeyProtect Service Instance GUID/UUID to create a ClientConfig
|
||||||
|
cc := kp.ClientConfig{
|
||||||
|
BaseURL: kp.DefaultBaseURL,
|
||||||
|
APIKey: "......",
|
||||||
|
InstanceID: "1234abcd-906d-438a-8a68-deadbeef1a2b3",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a new client from the config
|
||||||
|
client := kp.New(cc, kp.DefaultTransport())
|
||||||
|
|
||||||
|
// List keys in your KeyProtect instance
|
||||||
|
keys, err := client.GetKeys(context.Background(), 0, 0)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Migrating
|
||||||
|
|
||||||
|
For users of the original `key-protect-client` that is now deprecated, this library is a drop in replacement. Updating the package reference to `github.com/IBM/keyprotect-go-client` should be the only change needed. If you are worried about new incompatible changes, version `v0.3.1` of `key-protect-client` is equivalent to version `v0.3.3` of `keyprotect-go-client`, so pinning `v0.3.3` of the new library should be sufficient to pull from the new repo with no new functional changes.
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
The KeyProtect client requires a valid [IAM API Key](https://cloud.ibm.com/docs/iam?topic=iam-userapikey#create_user_key) that is passed via the `APIKey` field in the `ClientConfig`. The client will call IAM to get an access token for that API key, caches the access token, and reuses that token on subsequent calls. If the access token is expired, the client will call IAM to get a new access token.
|
||||||
|
|
||||||
|
Alternatively, you may also inject your own tokens during runtime. When using your own tokens, it's the responsibilty of the caller to ensure the access token is valid and is not expired. You can specify the access token in either the `ClientConfig` structure or on the context (see below.)
|
||||||
|
|
||||||
|
To specify authorization token on the context:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Create a ClientConfig and Client like before, but without an APIKey
|
||||||
|
cc := kp.ClientConfig{
|
||||||
|
BaseURL: kp.DefaultBaseURL,
|
||||||
|
InstanceID: "1234abcd-906d-438a-8a68-deadbeef1a2b3",
|
||||||
|
}
|
||||||
|
client := kp.New(cc, kp.DefaultTransport())
|
||||||
|
|
||||||
|
// Use NewContextWithAuth to add your token into the context
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx = kp.NewContextWithAuth(ctx, "Bearer ABCDEF123456....")
|
||||||
|
|
||||||
|
// List keys with our injected token via the context
|
||||||
|
keys, err := api.GetKeys(ctx, 0, 0)
|
||||||
|
```
|
||||||
|
|
||||||
|
For information on IAM API Keys and tokens please refer to the [IAM docs](https://cloud.ibm.com/docs/iam?topic=iam-manapikey)
|
||||||
|
|
||||||
|
## Finding a KeyProtect Service Instance's UUID
|
||||||
|
|
||||||
|
The client requires a valid UUID that identifies your KeyProtect Service Instance to be able to interact with your key data in the instance. An instance is somewhat like a folder or directory of keys; you can have many of them per account, but the keys they contain are separate and cannot be shared between instances.
|
||||||
|
|
||||||
|
The [IBM Cloud CLI](https://cloud.ibm.com/docs/cli?topic=cloud-cli-getting-started) can be used to find the UUID for your KeyProtect instance.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ic resource service-instances
|
||||||
|
OK
|
||||||
|
Name Location State Type
|
||||||
|
Key Protect-private us-south active service_instance
|
||||||
|
Key Protect-abc123 us-east active service_instance
|
||||||
|
```
|
||||||
|
|
||||||
|
Find the name of your KeyProtect instance as you created it, and the use the client to get its details. The Instance ID is the GUID field, or if you do not see GUID, it will be the last part of the CRN. For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ic resource service-instance "Key Protect-private"
|
||||||
|
OK
|
||||||
|
|
||||||
|
Name: Key Protect-private
|
||||||
|
ID: crn:v1:bluemix:public:kms:us-south:a/.......:1234abcd-906d-438a-8a68-deadbeef1a2b3::
|
||||||
|
GUID: 1234abcd-906d-438a-8a68-deadbeef1a2b3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Generating a root key (CRK)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Create a root key named MyRootKey with no expiration
|
||||||
|
key, err := client.CreateRootKey(ctx, "MyRootKey", nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
fmt.Println(key.ID, key.Name)
|
||||||
|
|
||||||
|
crkID := key.ID
|
||||||
|
```
|
||||||
|
|
||||||
|
### Wrapping and Unwrapping a DEK using a specific Root Key.
|
||||||
|
|
||||||
|
```go
|
||||||
|
myDEK := []byte{"thisisadataencryptionkey"}
|
||||||
|
// Do some encryption with myDEK
|
||||||
|
// Wrap the DEK so we can safely store it
|
||||||
|
wrappedDEK, err := client.Wrap(ctx, crkID, myDEK, nil)
|
||||||
|
|
||||||
|
|
||||||
|
// Unwrap the DEK
|
||||||
|
dek, err := client.Unwrap(ctx, crkID, wrappedDEK, nil)
|
||||||
|
// Do some encryption/decryption using the DEK
|
||||||
|
// Discard the DEK
|
||||||
|
dek = nil
|
||||||
|
```
|
||||||
|
|
||||||
|
Note you can also pass additional authentication data (AAD) to wrap and unwrap calls
|
||||||
|
to provide another level of protection for your DEK. The AAD is a string array with
|
||||||
|
each element up to 255 chars. For example:
|
||||||
|
|
||||||
|
```go
|
||||||
|
myAAD := []string{"First aad string", "second aad string", "third aad string"}
|
||||||
|
myDEK := []byte{"thisisadataencryptionkey"}
|
||||||
|
// Do some encryption with myDEK
|
||||||
|
// Wrap the DEK so we can safely store it
|
||||||
|
wrappedDEK, err := client.Wrap(ctx, crkID, myDEK, &myAAD)
|
||||||
|
|
||||||
|
|
||||||
|
// Unwrap the DEK
|
||||||
|
dek, err := client.Unwrap(ctx, crkID, wrappedDEK, &myAAD)
|
||||||
|
// Do some encryption/decryption using the DEK
|
||||||
|
// Discard the DEK
|
||||||
|
dek = nil
|
||||||
|
```
|
||||||
|
|
||||||
|
Have key protect create a DEK for you:
|
||||||
|
|
||||||
|
```go
|
||||||
|
dek, wrappedDek, err := client.WrapCreateDEK(ctx, crkID, nil)
|
||||||
|
// Do some encrypt/decrypt with the dek
|
||||||
|
// Discard the DEK
|
||||||
|
dek = nil
|
||||||
|
|
||||||
|
// Save the wrapped DEK for later. Use Unwrap to use it.
|
||||||
|
```
|
||||||
|
|
||||||
|
Can also specify AAD:
|
||||||
|
|
||||||
|
```go
|
||||||
|
myAAD := []string{"First aad string", "second aad string", "third aad string"}
|
||||||
|
dek, wrappedDek, err := client.WrapCreateDEK(ctx, crkID, &myAAD)
|
||||||
|
// Do some encrypt/decrypt with the dek
|
||||||
|
// Discard the DEK
|
||||||
|
dek = nil
|
||||||
|
|
||||||
|
// Save the wrapped DEK for later. Call Unwrap to use it, make
|
||||||
|
// sure to specify the same AAD.
|
||||||
|
```
|
252
vendor/github.com/IBM/keyprotect-go-client/iam/iam.go
generated
vendored
Normal file
252
vendor/github.com/IBM/keyprotect-go-client/iam/iam.go
generated
vendored
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
// Copyright 2019 IBM Corp.
|
||||||
|
//
|
||||||
|
// 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 iam
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
rhttp "github.com/hashicorp/go-retryablehttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IAMTokenURL is the global endpoint URL for the IAM token service
|
||||||
|
const IAMTokenURL = "https://iam.cloud.ibm.com/oidc/token"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// RetryWaitMax is the maximum time to wait between HTTP retries
|
||||||
|
RetryWaitMax = 30 * time.Second
|
||||||
|
|
||||||
|
// RetryMax is the max number of attempts to retry for failed HTTP requests
|
||||||
|
RetryMax = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
type TokenSource interface {
|
||||||
|
Token() (*Token, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CredentialFromAPIKey returns an IAMTokenSource that requests access tokens
|
||||||
|
// from the default token endpoint using an IAM API Key as the authentication mechanism
|
||||||
|
func CredentialFromAPIKey(apiKey string) *IAMTokenSource {
|
||||||
|
return &IAMTokenSource{
|
||||||
|
TokenURL: IAMTokenURL,
|
||||||
|
APIKey: apiKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token represents an IAM credential used to authorize requests to another service.
|
||||||
|
type Token struct {
|
||||||
|
AccessToken string
|
||||||
|
RefreshToken string
|
||||||
|
TokenType string
|
||||||
|
Expiry time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Token) Valid() bool {
|
||||||
|
if t == nil || t.AccessToken == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.Expiry.Before(time.Now()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// jsonToken is for deserializing the token from the response body
|
||||||
|
type jsonToken struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
ExpiresIn int32 `json:"expires_in"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// getExpireTime uses local time and the ExpiresIn offset to calculate an
|
||||||
|
// expiration time based off our local clock, which is more accurate for
|
||||||
|
// us to determine when it expires relative to our client.
|
||||||
|
// we also pad the time a bit, because long running requests can fail
|
||||||
|
// mid-request if we send a soon-to-expire token along
|
||||||
|
func (jt jsonToken) getExpireTime() time.Time {
|
||||||
|
// set the expiration time for 1 min less than the
|
||||||
|
// actual time to prevent timeout errors
|
||||||
|
return time.Now().Add(time.Duration(jt.ExpiresIn-60) * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IAMTokenSource is used to retrieve access tokens from the IAM token service.
|
||||||
|
// Most will probably want to use CredentialFromAPIKey to build an IAMTokenSource type,
|
||||||
|
// but it can also be created directly if one wishes to override the default IAM
|
||||||
|
// endpoint by setting TokenURL
|
||||||
|
type IAMTokenSource struct {
|
||||||
|
TokenURL string
|
||||||
|
APIKey string
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
|
t *Token
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token requests an access token from IAM using the IAMTokenSource config.
|
||||||
|
func (ts *IAMTokenSource) Token() (*Token, error) {
|
||||||
|
ts.mu.Lock()
|
||||||
|
defer ts.mu.Unlock()
|
||||||
|
|
||||||
|
if ts.t.Valid() {
|
||||||
|
return ts.t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if ts.APIKey == "" {
|
||||||
|
return nil, errors.New("iam: APIKey is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("grant_type", "urn:ibm:params:oauth:grant-type:apikey")
|
||||||
|
v.Set("apikey", ts.APIKey)
|
||||||
|
reqBody := []byte(v.Encode())
|
||||||
|
|
||||||
|
u, err := url.Parse(ts.TokenURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRequest will calculate Content-Length if we pass it a bytes.Buffer
|
||||||
|
// instead of a io.Reader type
|
||||||
|
bodyBuf := bytes.NewBuffer(reqBody)
|
||||||
|
request, err := rhttp.NewRequest("POST", u.String(), bodyBuf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
request.Header.Set("Accept", "application/json")
|
||||||
|
|
||||||
|
// use hashicorp retryable client with max wait time and attempts from module vars
|
||||||
|
client := rhttp.NewClient()
|
||||||
|
client.Logger = nil
|
||||||
|
client.RetryWaitMax = RetryWaitMax
|
||||||
|
client.RetryMax = RetryMax
|
||||||
|
client.ErrorHandler = rhttp.PassthroughErrorHandler
|
||||||
|
|
||||||
|
// need to use the go http DefaultTransport for tests to override with stubs (gock HTTP stubbing)
|
||||||
|
client.HTTPClient = &http.Client{
|
||||||
|
Timeout: time.Duration(60) * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the DefaultRetryPolicy but with retry on 429s as well
|
||||||
|
client.CheckRetry = func(ctx context.Context, resp *http.Response, err error) (bool, error) {
|
||||||
|
// do not retry on context.Canceled or context.DeadlineExceeded
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return false, ctx.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// retry on connection error (code == 0), all 500s except 501, and 429s
|
||||||
|
if resp.StatusCode == 0 || (resp.StatusCode >= 500 && resp.StatusCode != 501) || resp.StatusCode == 429 {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if _, err := buf.ReadFrom(resp.Body); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
var iamErr Error
|
||||||
|
if err = json.Unmarshal(buf.Bytes(), &iamErr); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
iamErr.HTTPResponse = resp
|
||||||
|
return nil, iamErr
|
||||||
|
}
|
||||||
|
|
||||||
|
var jToken jsonToken
|
||||||
|
if err = json.Unmarshal(buf.Bytes(), &jToken); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
token := &Token{
|
||||||
|
AccessToken: jToken.AccessToken,
|
||||||
|
RefreshToken: jToken.RefreshToken,
|
||||||
|
TokenType: jToken.TokenType,
|
||||||
|
Expiry: jToken.getExpireTime(),
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.t = token
|
||||||
|
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error is a type to hold error information that the IAM services sends back
|
||||||
|
// when a request cannot be completed. ErrorCode, ErrorMessage, and Context.RequestID
|
||||||
|
// are probably the most useful fields. IAM will most likely ask you for the RequestID
|
||||||
|
// if you ask for support.
|
||||||
|
//
|
||||||
|
// Also of note is that the http.Response object is included in HTTPResponse for
|
||||||
|
// error handling at the higher application levels.
|
||||||
|
type Error struct {
|
||||||
|
ErrorCode string `json:"errorCode"`
|
||||||
|
ErrorMessage string `json:"errorMessage"`
|
||||||
|
Context *iamRequestContext `json:"context"`
|
||||||
|
HTTPResponse *http.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
type iamRequestContext struct {
|
||||||
|
ClientIP string `json:"clientIp"`
|
||||||
|
ClusterName string `json:"clusterName"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
InstanceID string `json:"instanceId"`
|
||||||
|
RequestID string `json:"requestId"`
|
||||||
|
RequestType string `json:"requestType"`
|
||||||
|
ElapsedTime string `json:"elapsedTime"`
|
||||||
|
StartTime string `json:"startTime"`
|
||||||
|
EndTime string `json:"endTime"`
|
||||||
|
ThreadID string `json:"threadId"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
UserAgent string `json:"userAgent"`
|
||||||
|
Locale string `json:"locale"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ie Error) Error() string {
|
||||||
|
|
||||||
|
reqId := ""
|
||||||
|
if ie.Context != nil {
|
||||||
|
reqId = ie.Context.RequestID
|
||||||
|
}
|
||||||
|
|
||||||
|
statusCode := 0
|
||||||
|
if ie.HTTPResponse != nil {
|
||||||
|
statusCode = ie.HTTPResponse.StatusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("iam.Error: HTTP %d requestId='%s' message='%s %s'",
|
||||||
|
statusCode, reqId, ie.ErrorCode, ie.ErrorMessage)
|
||||||
|
}
|
219
vendor/github.com/IBM/keyprotect-go-client/import_token.go
generated
vendored
Normal file
219
vendor/github.com/IBM/keyprotect-go-client/import_token.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// Copyright 2019 IBM Corp.
|
||||||
|
//
|
||||||
|
// 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 kp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const importTokenEncAlgo = "RSAES_OAEP_SHA_256" // currently the only one supported
|
||||||
|
|
||||||
|
// ImportTokenCreateRequest represents request parameters for creating a
|
||||||
|
// ImportToken.
|
||||||
|
type ImportTokenCreateRequest struct {
|
||||||
|
MaxAllowedRetrievals int `json:"maxAllowedRetrievals,omitempty"`
|
||||||
|
ExpiresInSeconds int `json:"expiration,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImportTokenKeyResponse represents the response body for various ImportToken
|
||||||
|
// API calls.
|
||||||
|
type ImportTokenKeyResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
CreationDate *time.Time `json:"creationDate"`
|
||||||
|
ExpirationDate *time.Time `json:"expirationDate"`
|
||||||
|
Payload string `json:"payload"`
|
||||||
|
Nonce string `json:"nonce"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImportTokenMetadata represents the metadata of a ImportToken.
|
||||||
|
type ImportTokenMetadata struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
CreationDate *time.Time `json:"creationDate"`
|
||||||
|
ExpirationDate *time.Time `json:"expirationDate"`
|
||||||
|
MaxAllowedRetrievals int `json:"maxAllowedRetrievals"`
|
||||||
|
RemainingRetrievals int `json:"remainingRetrievals"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImportToken creates a key ImportToken.
|
||||||
|
func (c *Client) CreateImportToken(ctx context.Context, expiration, maxAllowedRetrievals int) (*ImportTokenMetadata, error) {
|
||||||
|
reqBody := ImportTokenCreateRequest{
|
||||||
|
MaxAllowedRetrievals: maxAllowedRetrievals,
|
||||||
|
ExpiresInSeconds: expiration,
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := c.newRequest("POST", "import_token", &reqBody)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res := ImportTokenMetadata{}
|
||||||
|
if _, err := c.do(ctx, req, &res); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetImportTokenTransportKey retrieves the ImportToken transport key.
|
||||||
|
func (c *Client) GetImportTokenTransportKey(ctx context.Context) (*ImportTokenKeyResponse, error) {
|
||||||
|
res := ImportTokenKeyResponse{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("GET", "import_token", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := c.do(ctx, req, &res); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptNonce will wrap the KP generated nonce with the users key-material
|
||||||
|
func EncryptNonce(key, value, iv string) (string, string, error) {
|
||||||
|
return encryptNonce(key, value, iv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptKey will encrypt the user key-material with the public key from key protect
|
||||||
|
func EncryptKey(key, pubkey string) (string, error) {
|
||||||
|
return encryptKey(key, pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encryptNonce(key, value, iv string) (string, string, error) {
|
||||||
|
var cipherText []byte
|
||||||
|
pubKey, err := base64.StdEncoding.DecodeString(key)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("Failed to decode public key: %s", err)
|
||||||
|
}
|
||||||
|
nonce, err := base64.StdEncoding.DecodeString(value)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("Failed to decode nonce: %s", err)
|
||||||
|
}
|
||||||
|
block, err := aes.NewCipher(pubKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
if iv == "" {
|
||||||
|
newIv := make([]byte, 12)
|
||||||
|
if _, err := io.ReadFull(rand.Reader, newIv); err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
cipherText = aesgcm.Seal(nil, newIv, nonce, nil)
|
||||||
|
return base64.StdEncoding.EncodeToString(cipherText), base64.StdEncoding.EncodeToString(newIv), nil
|
||||||
|
}
|
||||||
|
cipherText = aesgcm.Seal(nil, []byte(iv), nonce, nil)
|
||||||
|
return base64.StdEncoding.EncodeToString(cipherText), iv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptNonceWithCBCPAD encrypts the nonce using the user's key-material
|
||||||
|
// with CBC encrypter. It will also pad the nonce using pkcs7. This is needed
|
||||||
|
// for Hyper Protect Crypto Services, since it supports only CBC Encryption.
|
||||||
|
func EncryptNonceWithCBCPAD(key, value, iv string) (string, string, error) {
|
||||||
|
keyMat, err := base64.StdEncoding.DecodeString(key)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("Failed to decode Key: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nonce, err := base64.StdEncoding.DecodeString(value)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("Failed to decode Nonce: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
block, err := aes.NewCipher(keyMat)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PKCS7 Padding
|
||||||
|
paddingLength := aes.BlockSize - (len(nonce) % aes.BlockSize)
|
||||||
|
paddingBytes := []byte{byte(paddingLength)}
|
||||||
|
paddingText := bytes.Repeat(paddingBytes, paddingLength)
|
||||||
|
nonce = append(nonce, paddingText...)
|
||||||
|
|
||||||
|
var newIv []byte
|
||||||
|
if iv != "" {
|
||||||
|
newIv = []byte(iv)
|
||||||
|
} else {
|
||||||
|
newIv = make([]byte, aes.BlockSize)
|
||||||
|
// Generate an IV to achieve semantic security
|
||||||
|
if _, err := io.ReadFull(rand.Reader, newIv); err != nil {
|
||||||
|
return "", "", fmt.Errorf("Failed to generate IV: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cipherText := make([]byte, len(nonce))
|
||||||
|
|
||||||
|
mode := cipher.NewCBCEncrypter(block, newIv)
|
||||||
|
mode.CryptBlocks(cipherText, nonce)
|
||||||
|
|
||||||
|
return base64.StdEncoding.EncodeToString(cipherText), base64.StdEncoding.EncodeToString(newIv), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encryptKey uses sha256 to encrypt the key
|
||||||
|
func encryptKey(key, pubKey string) (string, error) {
|
||||||
|
return encryptKeyWithSHA(key, pubKey, sha256.New())
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptKeyWithSHA1 uses sha1 to encrypt the key
|
||||||
|
func EncryptKeyWithSHA1(key, pubKey string) (string, error) {
|
||||||
|
return encryptKeyWithSHA(key, pubKey, sha1.New())
|
||||||
|
}
|
||||||
|
|
||||||
|
func encryptKeyWithSHA(key, pubKey string, sha hash.Hash) (string, error) {
|
||||||
|
decodedPubKey, err := base64.StdEncoding.DecodeString(pubKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Failed to decode public key: %s", err)
|
||||||
|
}
|
||||||
|
keyMat, err := base64.StdEncoding.DecodeString(key)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Failed to decode key material: %s", err)
|
||||||
|
}
|
||||||
|
pubKeyBlock, _ := pem.Decode(decodedPubKey)
|
||||||
|
if pubKeyBlock == nil {
|
||||||
|
return "", fmt.Errorf("Failed to decode public key into pem format: %s", err)
|
||||||
|
}
|
||||||
|
parsedPubKey, err := x509.ParsePKIXPublicKey(pubKeyBlock.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Failed to parse public key: %s", err)
|
||||||
|
}
|
||||||
|
publicKey, isRSAPublicKey := parsedPubKey.(*rsa.PublicKey)
|
||||||
|
if !isRSAPublicKey {
|
||||||
|
return "", fmt.Errorf("invalid public key")
|
||||||
|
}
|
||||||
|
encryptedKey, err := rsa.EncryptOAEP(sha, rand.Reader, publicKey, keyMat, []byte(""))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Failed to encrypt key: %s", err)
|
||||||
|
}
|
||||||
|
return base64.StdEncoding.EncodeToString(encryptedKey), nil
|
||||||
|
}
|
543
vendor/github.com/IBM/keyprotect-go-client/instances.go
generated
vendored
Normal file
543
vendor/github.com/IBM/keyprotect-go-client/instances.go
generated
vendored
Normal file
@ -0,0 +1,543 @@
|
|||||||
|
// Copyright 2019 IBM Corp.
|
||||||
|
//
|
||||||
|
// 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 kp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DualAuthDelete defines the policy type as dual auth delete
|
||||||
|
DualAuthDelete = "dualAuthDelete"
|
||||||
|
|
||||||
|
// AllowedNetwork defines the policy type as allowed network
|
||||||
|
AllowedNetwork = "allowedNetwork"
|
||||||
|
|
||||||
|
// AllowedIP defines the policy type as allowed ip that are whitelisted
|
||||||
|
AllowedIP = "allowedIP"
|
||||||
|
|
||||||
|
// Metrics defines the policy type as metrics
|
||||||
|
Metrics = "metrics"
|
||||||
|
// KeyAccess defines the policy type as key create import access
|
||||||
|
KeyCreateImportAccess = "keyCreateImportAccess"
|
||||||
|
|
||||||
|
// KeyAccess policy attributes
|
||||||
|
CreateRootKey = "CreateRootKey"
|
||||||
|
CreateStandardKey = "CreateStandardKey"
|
||||||
|
ImportRootKey = "ImportRootKey"
|
||||||
|
ImportStandardKey = "ImportStandardKey"
|
||||||
|
EnforceToken = "EnforceToken"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// InstancePolicy represents a instance-level policy of a key as returned by the KP API.
|
||||||
|
// this policy enables dual authorization for deleting a key
|
||||||
|
type InstancePolicy struct {
|
||||||
|
CreatedBy string `json:"createdBy,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"creationDate,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"lastUpdated,omitempty"`
|
||||||
|
UpdatedBy string `json:"updatedBy,omitempty"`
|
||||||
|
PolicyType string `json:"policy_type,omitempty"`
|
||||||
|
PolicyData PolicyData `json:"policy_data,omitempty" mapstructure:"policyData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PolicyData contains the details of the policy type
|
||||||
|
type PolicyData struct {
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
Attributes *Attributes `json:"attributes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attributes contains the detals of allowed network policy type
|
||||||
|
type Attributes struct {
|
||||||
|
AllowedNetwork *string `json:"allowed_network,omitempty"`
|
||||||
|
AllowedIP IPAddresses `json:"allowed_ip,omitempty"`
|
||||||
|
CreateRootKey *bool `json:"create_root_key,omitempty"`
|
||||||
|
CreateStandardKey *bool `json:"create_standard_key,omitempty"`
|
||||||
|
ImportRootKey *bool `json:"import_root_key,omitempty"`
|
||||||
|
ImportStandardKey *bool `json:"import_standard_key,omitempty"`
|
||||||
|
EnforceToken *bool `json:"enforce_token,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPAddresses ...
|
||||||
|
type IPAddresses []string
|
||||||
|
|
||||||
|
// InstancePolicies represents a collection of Policies associated with Key Protect instances.
|
||||||
|
type InstancePolicies struct {
|
||||||
|
Metadata PoliciesMetadata `json:"metadata"`
|
||||||
|
Policies []InstancePolicy `json:"resources"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDualAuthInstancePolicy retrieves the dual auth delete policy details associated with the instance
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-dual-auth
|
||||||
|
func (c *Client) GetDualAuthInstancePolicy(ctx context.Context) (*InstancePolicy, error) {
|
||||||
|
policyResponse := InstancePolicies{}
|
||||||
|
|
||||||
|
err := c.getInstancePolicy(ctx, DualAuthDelete, &policyResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyResponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return &policyResponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllowedNetworkInstancePolicy retrieves the allowed network policy details associated with the instance.
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-managing-network-access-policies
|
||||||
|
func (c *Client) GetAllowedNetworkInstancePolicy(ctx context.Context) (*InstancePolicy, error) {
|
||||||
|
policyResponse := InstancePolicies{}
|
||||||
|
|
||||||
|
err := c.getInstancePolicy(ctx, AllowedNetwork, &policyResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyResponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyResponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllowedIPInstancePolicy retrieves the allowed IP instance policy details associated with the instance.
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-allowed-ip
|
||||||
|
func (c *Client) GetAllowedIPInstancePolicy(ctx context.Context) (*InstancePolicy, error) {
|
||||||
|
policyResponse := InstancePolicies{}
|
||||||
|
|
||||||
|
err := c.getInstancePolicy(ctx, AllowedIP, &policyResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyResponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyResponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKeyCreateImportAccessInstancePolicy retrieves the key create import access policy details associated with the instance.
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-keyCreateImportAccess
|
||||||
|
func (c *Client) GetKeyCreateImportAccessInstancePolicy(ctx context.Context) (*InstancePolicy, error) {
|
||||||
|
policyResponse := InstancePolicies{}
|
||||||
|
|
||||||
|
err := c.getInstancePolicy(ctx, KeyCreateImportAccess, &policyResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyResponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyResponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getInstancePolicy(ctx context.Context, policyType string, policyResponse *InstancePolicies) error {
|
||||||
|
req, err := c.newRequest("GET", "instance/policies", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("policy", policyType)
|
||||||
|
req.URL.RawQuery = v.Encode()
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &policyResponse)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMetricsInstancePolicy retrieves the metrics policy details associated with the instance
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-sysdig-metrics
|
||||||
|
func (c *Client) GetMetricsInstancePolicy(ctx context.Context) (*InstancePolicy, error) {
|
||||||
|
policyResponse := InstancePolicies{}
|
||||||
|
|
||||||
|
err := c.getInstancePolicy(ctx, Metrics, &policyResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyResponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return &policyResponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInstancePolicies retrieves all policies of an Instance.
|
||||||
|
func (c *Client) GetInstancePolicies(ctx context.Context) ([]InstancePolicy, error) {
|
||||||
|
policyresponse := InstancePolicies{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("GET", "instance/policies", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return policyresponse.Policies, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) setInstancePolicy(ctx context.Context, policyType string, policyRequest InstancePolicies) error {
|
||||||
|
req, err := c.newRequest("PUT", "instance/policies", &policyRequest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("policy", policyType)
|
||||||
|
req.URL.RawQuery = v.Encode()
|
||||||
|
|
||||||
|
policiesResponse := InstancePolicies{}
|
||||||
|
_, err = c.do(ctx, req, &policiesResponse)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDualAuthInstancePolicy updates the dual auth delete policy details associated with an instance
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-dual-auth
|
||||||
|
func (c *Client) SetDualAuthInstancePolicy(ctx context.Context, enable bool) error {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: DualAuthDelete,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &enable,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := InstancePolicies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: 1,
|
||||||
|
},
|
||||||
|
Policies: []InstancePolicy{policy},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.setInstancePolicy(ctx, DualAuthDelete, policyRequest)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAllowedIPInstancePolices updates the allowed IP instance policy details associated with an instance.
|
||||||
|
// For more information can refet to the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-allowed-ip
|
||||||
|
func (c *Client) SetAllowedIPInstancePolicy(ctx context.Context, enable bool, allowedIPs []string) error {
|
||||||
|
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: AllowedIP,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &enable,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// The IP address validation is performed by the key protect service.
|
||||||
|
if enable && len(allowedIPs) != 0 {
|
||||||
|
policy.PolicyData.Attributes = &Attributes{}
|
||||||
|
policy.PolicyData.Attributes.AllowedIP = allowedIPs
|
||||||
|
} else if enable && len(allowedIPs) == 0 {
|
||||||
|
return fmt.Errorf("Please provide at least 1 IP subnet specified with CIDR notation")
|
||||||
|
} else if !enable && len(allowedIPs) != 0 {
|
||||||
|
return fmt.Errorf("IP address list should only be provided if the policy is being enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := InstancePolicies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: 1,
|
||||||
|
},
|
||||||
|
Policies: []InstancePolicy{policy},
|
||||||
|
}
|
||||||
|
err := c.setInstancePolicy(ctx, AllowedIP, policyRequest)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAllowedNetWorkInstancePolicy updates the allowed network policy details associated with an instance
|
||||||
|
// For more information can refer to the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-managing-network-access-policies
|
||||||
|
func (c *Client) SetAllowedNetworkInstancePolicy(ctx context.Context, enable bool, networkType string) error {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: AllowedNetwork,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &enable,
|
||||||
|
Attributes: &Attributes{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if networkType != "" {
|
||||||
|
policy.PolicyData.Attributes.AllowedNetwork = &networkType
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := InstancePolicies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: 1,
|
||||||
|
},
|
||||||
|
Policies: []InstancePolicy{policy},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.setInstancePolicy(ctx, AllowedNetwork, policyRequest)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMetricsInstancePolicy updates the metrics policy details associated with an instance
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-sysdig-metrics
|
||||||
|
func (c *Client) SetMetricsInstancePolicy(ctx context.Context, enable bool) error {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: Metrics,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &enable,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := InstancePolicies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: 1,
|
||||||
|
},
|
||||||
|
Policies: []InstancePolicy{policy},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.setInstancePolicy(ctx, Metrics, policyRequest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetKeyCreateImportAccessInstancePolicy updates the key create import access policy details associated with an instance.
|
||||||
|
// For more information, please refer to the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-keyCreateImportAccess
|
||||||
|
func (c *Client) SetKeyCreateImportAccessInstancePolicy(ctx context.Context, enable bool, attributes map[string]bool) error {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: KeyCreateImportAccess,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &enable,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if enable {
|
||||||
|
policy.PolicyData.Attributes = &Attributes{}
|
||||||
|
a := policy.PolicyData.Attributes
|
||||||
|
if val, ok := attributes[CreateRootKey]; ok {
|
||||||
|
a.CreateRootKey = &val
|
||||||
|
}
|
||||||
|
if val, ok := attributes[CreateStandardKey]; ok {
|
||||||
|
a.CreateStandardKey = &val
|
||||||
|
}
|
||||||
|
if val, ok := attributes[ImportRootKey]; ok {
|
||||||
|
a.ImportRootKey = &val
|
||||||
|
}
|
||||||
|
if val, ok := attributes[ImportStandardKey]; ok {
|
||||||
|
a.ImportStandardKey = &val
|
||||||
|
}
|
||||||
|
if val, ok := attributes[EnforceToken]; ok {
|
||||||
|
a.EnforceToken = &val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := InstancePolicies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: 1,
|
||||||
|
},
|
||||||
|
Policies: []InstancePolicy{policy},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.setInstancePolicy(ctx, KeyCreateImportAccess, policyRequest)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// BasicPolicyData defines the attribute input for the policy that supports only enabled parameter
|
||||||
|
type BasicPolicyData struct {
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowedNetworkPolicyData defines the attribute input for the Allowed Network instance policy
|
||||||
|
type AllowedNetworkPolicyData struct {
|
||||||
|
Enabled bool
|
||||||
|
Network string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowedIPPolicyData defines the attribute input for the Allowed IP instance policy
|
||||||
|
type AllowedIPPolicyData struct {
|
||||||
|
Enabled bool
|
||||||
|
IPAddresses IPAddresses
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyAccessInstancePolicyData defines the attribute input for the Key Create Import Access instance policy
|
||||||
|
type KeyCreateImportAccessInstancePolicy struct {
|
||||||
|
Enabled bool
|
||||||
|
CreateRootKey bool
|
||||||
|
CreateStandardKey bool
|
||||||
|
ImportRootKey bool
|
||||||
|
ImportStandardKey bool
|
||||||
|
EnforceToken bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// MultiplePolicies defines the input for the SetInstancPolicies method that can hold multiple policy details
|
||||||
|
type MultiplePolicies struct {
|
||||||
|
DualAuthDelete *BasicPolicyData
|
||||||
|
AllowedNetwork *AllowedNetworkPolicyData
|
||||||
|
AllowedIP *AllowedIPPolicyData
|
||||||
|
Metrics *BasicPolicyData
|
||||||
|
KeyCreateImportAccess *KeyCreateImportAccessInstancePolicy
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetInstancePolicies updates single or multiple policy details of an instance.
|
||||||
|
func (c *Client) SetInstancePolicies(ctx context.Context, policies MultiplePolicies) error {
|
||||||
|
var resPolicies []InstancePolicy
|
||||||
|
|
||||||
|
if policies.DualAuthDelete != nil {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: DualAuthDelete,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &(policies.DualAuthDelete.Enabled),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resPolicies = append(resPolicies, policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if policies.AllowedNetwork != nil {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: AllowedNetwork,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &(policies.AllowedNetwork.Enabled),
|
||||||
|
Attributes: &Attributes{
|
||||||
|
AllowedNetwork: &(policies.AllowedNetwork.Network),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resPolicies = append(resPolicies, policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if policies.AllowedIP != nil {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: AllowedIP,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &(policies.AllowedIP.Enabled),
|
||||||
|
Attributes: &Attributes{
|
||||||
|
AllowedIP: policies.AllowedIP.IPAddresses,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resPolicies = append(resPolicies, policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if policies.Metrics != nil {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: Metrics,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &(policies.Metrics.Enabled),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resPolicies = append(resPolicies, policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if policies.KeyCreateImportAccess != nil {
|
||||||
|
policy := InstancePolicy{
|
||||||
|
PolicyType: KeyCreateImportAccess,
|
||||||
|
PolicyData: PolicyData{
|
||||||
|
Enabled: &(policies.KeyCreateImportAccess.Enabled),
|
||||||
|
Attributes: &Attributes{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if policies.KeyCreateImportAccess.CreateRootKey {
|
||||||
|
policy.PolicyData.Attributes.CreateRootKey = &policies.KeyCreateImportAccess.CreateRootKey
|
||||||
|
}
|
||||||
|
if policies.KeyCreateImportAccess.CreateStandardKey {
|
||||||
|
policy.PolicyData.Attributes.CreateStandardKey = &policies.KeyCreateImportAccess.CreateStandardKey
|
||||||
|
}
|
||||||
|
if policies.KeyCreateImportAccess.ImportRootKey {
|
||||||
|
policy.PolicyData.Attributes.ImportRootKey = &policies.KeyCreateImportAccess.ImportRootKey
|
||||||
|
}
|
||||||
|
if policies.KeyCreateImportAccess.ImportStandardKey {
|
||||||
|
policy.PolicyData.Attributes.ImportStandardKey = &policies.KeyCreateImportAccess.ImportStandardKey
|
||||||
|
}
|
||||||
|
if policies.KeyCreateImportAccess.EnforceToken {
|
||||||
|
policy.PolicyData.Attributes.EnforceToken = &policies.KeyCreateImportAccess.EnforceToken
|
||||||
|
}
|
||||||
|
|
||||||
|
resPolicies = append(resPolicies, policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := InstancePolicies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: len(resPolicies),
|
||||||
|
},
|
||||||
|
Policies: resPolicies,
|
||||||
|
}
|
||||||
|
|
||||||
|
policyresponse := Policies{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("PUT", "instance/policies", &policyRequest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &policyresponse)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type portsMetadata struct {
|
||||||
|
CollectionType string `json:"collectionType"`
|
||||||
|
NumberOfPorts int `json:"collectionTotal"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type portResponse struct {
|
||||||
|
Metadata portsMetadata `json:"metadata"`
|
||||||
|
Ports []privatePort `json:"resources"`
|
||||||
|
}
|
||||||
|
type privatePort struct {
|
||||||
|
PrivatePort int `json:"private_endpoint_port,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllowedIPPrivateNetworkPort retrieves the private endpoint port assigned to allowed ip policy.
|
||||||
|
func (c *Client) GetAllowedIPPrivateNetworkPort(ctx context.Context) (int, error) {
|
||||||
|
var portResponse portResponse
|
||||||
|
|
||||||
|
req, err := c.newRequest("GET", "instance/allowed_ip_port", nil)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &portResponse)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(portResponse.Ports) == 0 {
|
||||||
|
return 0, fmt.Errorf("No port number available. Please check the instance has an enabled allowedIP policy")
|
||||||
|
}
|
||||||
|
return portResponse.Ports[0].PrivatePort, nil
|
||||||
|
}
|
68
vendor/github.com/IBM/keyprotect-go-client/key_alias.go
generated
vendored
Normal file
68
vendor/github.com/IBM/keyprotect-go-client/key_alias.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package kp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
requestPath = "keys/%s/aliases/%s"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KeyAlias represents an Alias details of a key as returned by KP API
|
||||||
|
type KeyAlias struct {
|
||||||
|
KeyID string `json:"keyId,omitempty"`
|
||||||
|
Alias string `json:"alias,omitempty"`
|
||||||
|
CreatedBy string `json:"createdBy,omitempty"`
|
||||||
|
CreationDate *time.Time `json:"creationDate,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AliasesMetadata represents the metadata of a collection of aliases
|
||||||
|
type AliasesMetadata struct {
|
||||||
|
CollectionType string `json:"collectionType"`
|
||||||
|
NumberOfAliases int `json:"collectionTotal"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeyAliases struct {
|
||||||
|
Metadata AliasesMetadata `json:"metadata"`
|
||||||
|
KeyAliases []KeyAlias `json:"resources"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateKeyAlias creates an alias name for a key.
|
||||||
|
// An alias name acts as an identifier just like key ID
|
||||||
|
// For more information please refer to the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-create-key-alias#create-key-alias-api
|
||||||
|
func (c *Client) CreateKeyAlias(ctx context.Context, aliasName, keyID string) (*KeyAlias, error) {
|
||||||
|
|
||||||
|
req, err := c.newRequest("POST", fmt.Sprintf(requestPath, keyID, aliasName), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
aliasesResponse := KeyAliases{}
|
||||||
|
_, err = c.do(ctx, req, &aliasesResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(aliasesResponse.KeyAliases) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &aliasesResponse.KeyAliases[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteKeyAlias deletes an alias name associated with a key
|
||||||
|
// For more information please refer to the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-create-key-alias#delete-key-alias
|
||||||
|
func (c *Client) DeleteKeyAlias(ctx context.Context, aliasName, keyID string) error {
|
||||||
|
|
||||||
|
req, err := c.newRequest("DELETE", fmt.Sprintf(requestPath, keyID, aliasName), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = c.do(ctx, req, nil)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
75
vendor/github.com/IBM/keyprotect-go-client/key_rings.go
generated
vendored
Normal file
75
vendor/github.com/IBM/keyprotect-go-client/key_rings.go
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package kp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
path = "key_rings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KeyRing struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
CreationDate *time.Time `json:"creationDate,omitempty"`
|
||||||
|
CreatedBy string `json:"createdBy,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeyRings struct {
|
||||||
|
Metadata KeysMetadata `json:"metadata"`
|
||||||
|
KeyRings []KeyRing `json:"resources"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRing method creates a key ring in the instance with the provided name
|
||||||
|
// For information please refer to the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-managing-key-rings#create-key-ring-api
|
||||||
|
func (c *Client) CreateKeyRing(ctx context.Context, id string) error {
|
||||||
|
|
||||||
|
req, err := c.newRequest("POST", fmt.Sprintf(path+"/%s", id), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRings method retrieves all the key rings associated with the instance
|
||||||
|
// For information please refer to the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-managing-key-rings#list-key-ring-api
|
||||||
|
func (c *Client) GetKeyRings(ctx context.Context) (*KeyRings, error) {
|
||||||
|
rings := KeyRings{}
|
||||||
|
req, err := c.newRequest("GET", path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &rings)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &rings, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRing method deletes the key ring with the provided name in the instance
|
||||||
|
// For information please refer to the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-managing-key-rings#delete-key-ring-api
|
||||||
|
func (c *Client) DeleteKeyRing(ctx context.Context, id string) error {
|
||||||
|
req, err := c.newRequest("DELETE", fmt.Sprintf(path+"/%s", id), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
463
vendor/github.com/IBM/keyprotect-go-client/keys.go
generated
vendored
Normal file
463
vendor/github.com/IBM/keyprotect-go-client/keys.go
generated
vendored
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
// Copyright 2019 IBM Corp.
|
||||||
|
//
|
||||||
|
// 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 kp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ReturnMinimal PreferReturn = 0
|
||||||
|
ReturnRepresentation PreferReturn = 1
|
||||||
|
|
||||||
|
keyType = "application/vnd.ibm.kms.key+json"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
preferHeaders = []string{"return=minimal", "return=representation"}
|
||||||
|
)
|
||||||
|
|
||||||
|
// PreferReturn designates the value for the "Prefer" header.
|
||||||
|
type PreferReturn int
|
||||||
|
|
||||||
|
// Key represents a key as returned by the KP API.
|
||||||
|
type Key struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
Tags []string `json:"Tags,omitempty"`
|
||||||
|
Aliases []string `json:"aliases,omitempty"`
|
||||||
|
AlgorithmType string `json:"algorithmType,omitempty"`
|
||||||
|
CreatedBy string `json:"createdBy,omitempty"`
|
||||||
|
CreationDate *time.Time `json:"creationDate,omitempty"`
|
||||||
|
LastUpdateDate *time.Time `json:"lastUpdateDate,omitempty"`
|
||||||
|
LastRotateDate *time.Time `json:"lastRotateDate,omitempty"`
|
||||||
|
KeyVersion *KeyVersion `json:"keyVersion,omitempty" mapstructure:keyVersion`
|
||||||
|
KeyRingID string `json:"keyRingID,omitempty"`
|
||||||
|
Extractable bool `json:"extractable"`
|
||||||
|
Expiration *time.Time `json:"expirationDate,omitempty"`
|
||||||
|
Imported bool `json:"imported,omitempty"`
|
||||||
|
Payload string `json:"payload,omitempty"`
|
||||||
|
State int `json:"state,omitempty"`
|
||||||
|
EncryptionAlgorithm string `json:"encryptionAlgorithm,omitempty"`
|
||||||
|
CRN string `json:"crn,omitempty"`
|
||||||
|
EncryptedNonce string `json:"encryptedNonce,omitempty"`
|
||||||
|
IV string `json:"iv,omitempty"`
|
||||||
|
Deleted *bool `json:"deleted,omitempty"`
|
||||||
|
DeletedBy *string `json:"deletedBy,omitempty"`
|
||||||
|
DeletionDate *time.Time `json:"deletionDate,omitempty"`
|
||||||
|
DualAuthDelete *DualAuth `json:"dualAuthDelete,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeysMetadata represents the metadata of a collection of keys.
|
||||||
|
type KeysMetadata struct {
|
||||||
|
CollectionType string `json:"collectionType"`
|
||||||
|
NumberOfKeys int `json:"collectionTotal"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keys represents a collection of Keys.
|
||||||
|
type Keys struct {
|
||||||
|
Metadata KeysMetadata `json:"metadata"`
|
||||||
|
Keys []Key `json:"resources"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeysActionRequest represents request parameters for a key action
|
||||||
|
// API call.
|
||||||
|
type KeysActionRequest struct {
|
||||||
|
PlainText string `json:"plaintext,omitempty"`
|
||||||
|
AAD []string `json:"aad,omitempty"`
|
||||||
|
CipherText string `json:"ciphertext,omitempty"`
|
||||||
|
Payload string `json:"payload,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeyVersion struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
CreationDate *time.Time `json:"creationDate,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateKey creates a new KP key.
|
||||||
|
func (c *Client) CreateKey(ctx context.Context, name string, expiration *time.Time, extractable bool) (*Key, error) {
|
||||||
|
return c.CreateImportedKey(ctx, name, expiration, "", "", "", extractable)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImportedKey creates a new KP key from the given key material.
|
||||||
|
func (c *Client) CreateImportedKey(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool) (*Key, error) {
|
||||||
|
key := Key{
|
||||||
|
Name: name,
|
||||||
|
Type: keyType,
|
||||||
|
Extractable: extractable,
|
||||||
|
Payload: payload,
|
||||||
|
}
|
||||||
|
|
||||||
|
if payload != "" && encryptedNonce != "" && iv != "" {
|
||||||
|
key.EncryptedNonce = encryptedNonce
|
||||||
|
key.IV = iv
|
||||||
|
key.EncryptionAlgorithm = importTokenEncAlgo
|
||||||
|
}
|
||||||
|
|
||||||
|
if expiration != nil {
|
||||||
|
key.Expiration = expiration
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.createKey(ctx, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRootKey creates a new, non-extractable key resource without
|
||||||
|
// key material.
|
||||||
|
func (c *Client) CreateRootKey(ctx context.Context, name string, expiration *time.Time) (*Key, error) {
|
||||||
|
return c.CreateKey(ctx, name, expiration, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateStandardKey creates a new, extractable key resource without
|
||||||
|
// key material.
|
||||||
|
func (c *Client) CreateStandardKey(ctx context.Context, name string, expiration *time.Time) (*Key, error) {
|
||||||
|
return c.CreateKey(ctx, name, expiration, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImportedRootKey creates a new, non-extractable key resource
|
||||||
|
// with the given key material.
|
||||||
|
func (c *Client) CreateImportedRootKey(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string) (*Key, error) {
|
||||||
|
return c.CreateImportedKey(ctx, name, expiration, payload, encryptedNonce, iv, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateStandardKey creates a new, extractable key resource with the
|
||||||
|
// given key material.
|
||||||
|
func (c *Client) CreateImportedStandardKey(ctx context.Context, name string, expiration *time.Time, payload string) (*Key, error) {
|
||||||
|
return c.CreateImportedKey(ctx, name, expiration, payload, "", "", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateKeyWithAliaes creats a new key with alias names. A key can have a maximum of 5 alias names.
|
||||||
|
// For more information please refer to the links below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-create-root-keys#create-root-key-api
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-create-standard-keys#create-standard-key-api
|
||||||
|
func (c *Client) CreateKeyWithAliases(ctx context.Context, name string, expiration *time.Time, extractable bool, aliases []string) (*Key, error) {
|
||||||
|
return c.CreateImportedKeyWithAliases(ctx, name, expiration, "", "", "", extractable, aliases)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImportedKeyWithAliases creates a new key with alias name and provided key material. A key can have a maximum of 5 alias names
|
||||||
|
// When importing root keys with import-token encryptedNonce and iv need to passed along with payload.
|
||||||
|
// Standard Keys cannot be imported with an import token hence only payload is required.
|
||||||
|
// For more information please refer to the links below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-import-root-keys#import-root-key-api
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-import-standard-keys#import-standard-key-gui
|
||||||
|
func (c *Client) CreateImportedKeyWithAliases(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool, aliases []string) (*Key, error) {
|
||||||
|
key := Key{
|
||||||
|
Name: name,
|
||||||
|
Type: keyType,
|
||||||
|
Extractable: extractable,
|
||||||
|
Payload: payload,
|
||||||
|
Aliases: aliases,
|
||||||
|
}
|
||||||
|
|
||||||
|
if !extractable && payload != "" && encryptedNonce != "" && iv != "" {
|
||||||
|
key.EncryptedNonce = encryptedNonce
|
||||||
|
key.IV = iv
|
||||||
|
key.EncryptionAlgorithm = importTokenEncAlgo
|
||||||
|
}
|
||||||
|
|
||||||
|
if expiration != nil {
|
||||||
|
key.Expiration = expiration
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.createKey(ctx, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) createKey(ctx context.Context, key Key) (*Key, error) {
|
||||||
|
keysRequest := Keys{
|
||||||
|
Metadata: KeysMetadata{
|
||||||
|
CollectionType: keyType,
|
||||||
|
NumberOfKeys: 1,
|
||||||
|
},
|
||||||
|
Keys: []Key{key},
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := c.newRequest("POST", "keys", &keysRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
keysResponse := Keys{}
|
||||||
|
if _, err := c.do(ctx, req, &keysResponse); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &keysResponse.Keys[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKeys retrieves a collection of keys that can be paged through.
|
||||||
|
func (c *Client) GetKeys(ctx context.Context, limit int, offset int) (*Keys, error) {
|
||||||
|
if limit == 0 {
|
||||||
|
limit = 2000
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := c.newRequest("GET", "keys", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("limit", strconv.Itoa(limit))
|
||||||
|
v.Set("offset", strconv.Itoa(offset))
|
||||||
|
req.URL.RawQuery = v.Encode()
|
||||||
|
|
||||||
|
keys := Keys{}
|
||||||
|
_, err = c.do(ctx, req, &keys)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &keys, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKey retrieves a key by ID or alias name.
|
||||||
|
// For more information on Key Alias please refer to the link below
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-retrieve-key
|
||||||
|
func (c *Client) GetKey(ctx context.Context, idOrAlias string) (*Key, error) {
|
||||||
|
return c.getKey(ctx, idOrAlias, "keys/%s")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKeyMetadata retrieves the metadata of a Key by ID or alias name.
|
||||||
|
// Note that the "/api/v2/keys/{id}/metadata" API does not return the payload,
|
||||||
|
// therefore the payload attribute in the Key pointer will always be empty.
|
||||||
|
// If you need the payload, you need to use the GetKey() function with the
|
||||||
|
// correct service access role.
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-manage-access#service-access-roles
|
||||||
|
func (c *Client) GetKeyMetadata(ctx context.Context, idOrAlias string) (*Key, error) {
|
||||||
|
return c.getKey(ctx, idOrAlias, "keys/%s/metadata")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getKey(ctx context.Context, id string, path string) (*Key, error) {
|
||||||
|
keys := Keys{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("GET", fmt.Sprintf(path, id), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &keys)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &keys.Keys[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CallOpt interface{}
|
||||||
|
|
||||||
|
type ForceOpt struct {
|
||||||
|
Force bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteKey deletes a key resource by specifying the ID of the key.
|
||||||
|
func (c *Client) DeleteKey(ctx context.Context, id string, prefer PreferReturn, callOpts ...CallOpt) (*Key, error) {
|
||||||
|
|
||||||
|
req, err := c.newRequest("DELETE", fmt.Sprintf("keys/%s", id), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range callOpts {
|
||||||
|
switch v := opt.(type) {
|
||||||
|
case ForceOpt:
|
||||||
|
params := url.Values{}
|
||||||
|
params.Set("force", strconv.FormatBool(v.Force))
|
||||||
|
req.URL.RawQuery = params.Encode()
|
||||||
|
default:
|
||||||
|
log.Printf("WARNING: Ignoring invalid CallOpt passed to DeleteKey: %v\n", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Prefer", preferHeaders[prefer])
|
||||||
|
|
||||||
|
keys := Keys{}
|
||||||
|
_, err = c.do(ctx, req, &keys)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(keys.Keys) > 0 {
|
||||||
|
return &keys.Keys[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestoreKey method reverts a delete key status to active key
|
||||||
|
// This method performs restore of any key from deleted state to active state.
|
||||||
|
// For more information please refer to the link below:
|
||||||
|
// https://cloud.ibm.com/dowcs/key-protect?topic=key-protect-restore-keys
|
||||||
|
func (c *Client) RestoreKey(ctx context.Context, id string) (*Key, error) {
|
||||||
|
req, err := c.newRequest("POST", fmt.Sprintf("keys/%s/restore", id), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
keysResponse := Keys{}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &keysResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &keysResponse.Keys[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap calls the wrap action with the given plain text.
|
||||||
|
func (c *Client) Wrap(ctx context.Context, id string, plainText []byte, additionalAuthData *[]string) ([]byte, error) {
|
||||||
|
_, ct, err := c.wrap(ctx, id, plainText, additionalAuthData)
|
||||||
|
return ct, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapCreateDEK calls the wrap action without plain text.
|
||||||
|
func (c *Client) WrapCreateDEK(ctx context.Context, id string, additionalAuthData *[]string) ([]byte, []byte, error) {
|
||||||
|
return c.wrap(ctx, id, nil, additionalAuthData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) wrap(ctx context.Context, id string, plainText []byte, additionalAuthData *[]string) ([]byte, []byte, error) {
|
||||||
|
keysActionReq := &KeysActionRequest{}
|
||||||
|
|
||||||
|
if plainText != nil {
|
||||||
|
_, err := base64.StdEncoding.DecodeString(string(plainText))
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
keysActionReq.PlainText = string(plainText)
|
||||||
|
}
|
||||||
|
|
||||||
|
if additionalAuthData != nil {
|
||||||
|
keysActionReq.AAD = *additionalAuthData
|
||||||
|
}
|
||||||
|
|
||||||
|
keysAction, err := c.doKeysAction(ctx, id, "wrap", keysActionReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pt := []byte(keysAction.PlainText)
|
||||||
|
ct := []byte(keysAction.CipherText)
|
||||||
|
|
||||||
|
return pt, ct, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap is deprecated since it returns only plaintext and doesn't know how to handle rotation.
|
||||||
|
func (c *Client) Unwrap(ctx context.Context, id string, cipherText []byte, additionalAuthData *[]string) ([]byte, error) {
|
||||||
|
plainText, _, err := c.UnwrapV2(ctx, id, cipherText, additionalAuthData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return plainText, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap with rotation support.
|
||||||
|
func (c *Client) UnwrapV2(ctx context.Context, id string, cipherText []byte, additionalAuthData *[]string) ([]byte, []byte, error) {
|
||||||
|
|
||||||
|
keysAction := &KeysActionRequest{
|
||||||
|
CipherText: string(cipherText),
|
||||||
|
}
|
||||||
|
|
||||||
|
if additionalAuthData != nil {
|
||||||
|
keysAction.AAD = *additionalAuthData
|
||||||
|
}
|
||||||
|
|
||||||
|
respAction, err := c.doKeysAction(ctx, id, "unwrap", keysAction)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
plainText := []byte(respAction.PlainText)
|
||||||
|
rewrapped := []byte(respAction.CipherText)
|
||||||
|
|
||||||
|
return plainText, rewrapped, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate rotates a CRK.
|
||||||
|
func (c *Client) Rotate(ctx context.Context, id, payload string) error {
|
||||||
|
|
||||||
|
actionReq := &KeysActionRequest{
|
||||||
|
Payload: payload,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := c.doKeysAction(ctx, id, "rotate", actionReq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable a key. The key will not be deleted but it will not be active
|
||||||
|
// and key operations cannot be performed on a disabled key.
|
||||||
|
// For more information can refer to the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-disable-keys
|
||||||
|
func (c *Client) DisableKey(ctx context.Context, id string) error {
|
||||||
|
_, err := c.doKeysAction(ctx, id, "disable", nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable a key. Only disabled keys can be enabled. After enable
|
||||||
|
// the key becomes active and key operations can be performed on it.
|
||||||
|
// Note: This does not recover Deleted keys.
|
||||||
|
// For more information can refer to the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-disable-keys#enable-api
|
||||||
|
func (c *Client) EnableKey(ctx context.Context, id string) error {
|
||||||
|
_, err := c.doKeysAction(ctx, id, "enable", nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitiateDualAuthDelete sets a key for deletion. The key must be configured with a DualAuthDelete policy.
|
||||||
|
// After the key is set to deletion it can be deleted by another user who has Manager access.
|
||||||
|
// For more information refer to the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-delete-dual-auth-keys#set-key-deletion-api
|
||||||
|
func (c *Client) InitiateDualAuthDelete(ctx context.Context, id string) error {
|
||||||
|
_, err := c.doKeysAction(ctx, id, "setKeyForDeletion", nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelDualAuthDelete unsets the key for deletion. If a key is set for deletion, it can
|
||||||
|
// be prevented from getting deleted by unsetting the key for deletion.
|
||||||
|
// For more information refer to the Key Protect docs in the link below:
|
||||||
|
//https://cloud.ibm.com/docs/key-protect?topic=key-protect-delete-dual-auth-keys#unset-key-deletion-api
|
||||||
|
func (c *Client) CancelDualAuthDelete(ctx context.Context, id string) error {
|
||||||
|
_, err := c.doKeysAction(ctx, id, "unsetKeyForDeletion", nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// doKeysAction calls the KP Client to perform an action on a key.
|
||||||
|
func (c *Client) doKeysAction(ctx context.Context, id string, action string, keysActionReq *KeysActionRequest) (*KeysActionRequest, error) {
|
||||||
|
keyActionRsp := KeysActionRequest{}
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("action", action)
|
||||||
|
|
||||||
|
req, err := c.newRequest("POST", fmt.Sprintf("keys/%s", id), keysActionReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.URL.RawQuery = v.Encode()
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &keyActionRsp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &keyActionRsp, nil
|
||||||
|
}
|
510
vendor/github.com/IBM/keyprotect-go-client/kp.go
generated
vendored
Normal file
510
vendor/github.com/IBM/keyprotect-go-client/kp.go
generated
vendored
Normal file
@ -0,0 +1,510 @@
|
|||||||
|
// Copyright 2019 IBM Corp.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// keyprotect-go-client is a Go client library for interacting with the IBM KeyProtect service.
|
||||||
|
package kp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
rhttp "github.com/hashicorp/go-retryablehttp"
|
||||||
|
|
||||||
|
"github.com/IBM/keyprotect-go-client/iam"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultBaseURL ...
|
||||||
|
DefaultBaseURL = "https://us-south.kms.cloud.ibm.com"
|
||||||
|
// DefaultTokenURL ..
|
||||||
|
DefaultTokenURL = iam.IAMTokenURL
|
||||||
|
|
||||||
|
// VerboseNone ...
|
||||||
|
VerboseNone = 0
|
||||||
|
// VerboseBodyOnly ...
|
||||||
|
VerboseBodyOnly = 1
|
||||||
|
// VerboseAll ...
|
||||||
|
VerboseAll = 2
|
||||||
|
// VerboseFailOnly ...
|
||||||
|
VerboseFailOnly = 3
|
||||||
|
// VerboseAllNoRedact ...
|
||||||
|
VerboseAllNoRedact = 4
|
||||||
|
|
||||||
|
authContextKey ContextKey = 0
|
||||||
|
defaultTimeout = 30 // in seconds.
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// RetryWaitMax is the maximum time to wait between HTTP retries
|
||||||
|
RetryWaitMax = 30 * time.Second
|
||||||
|
|
||||||
|
// RetryMax is the max number of attempts to retry for failed HTTP requests
|
||||||
|
RetryMax = 4
|
||||||
|
|
||||||
|
cidCtxKey = ctxKey("X-Correlation-Id")
|
||||||
|
)
|
||||||
|
|
||||||
|
type ctxKey string
|
||||||
|
|
||||||
|
// ClientConfig ...
|
||||||
|
type ClientConfig struct {
|
||||||
|
BaseURL string
|
||||||
|
Authorization string // The IBM Cloud (Bluemix) access token
|
||||||
|
APIKey string // Service ID API key, can be used instead of an access token
|
||||||
|
TokenURL string // The URL used to get an access token from the API key
|
||||||
|
InstanceID string // The IBM Cloud (Bluemix) instance ID that identifies your Key Protect service instance.
|
||||||
|
KeyRing string // The ID of the target Key Ring the key is associated with. It is optional but recommended for better performance.
|
||||||
|
Verbose int // See verbose values above
|
||||||
|
Timeout float64 // KP request timeout in seconds.
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultTransport ...
|
||||||
|
func DefaultTransport() http.RoundTripper {
|
||||||
|
transport := &http.Transport{
|
||||||
|
DisableKeepAlives: true,
|
||||||
|
MaxIdleConnsPerHost: -1,
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return transport
|
||||||
|
}
|
||||||
|
|
||||||
|
// API is deprecated. Use Client instead.
|
||||||
|
type API = Client
|
||||||
|
|
||||||
|
// Client holds configuration and auth information to interact with KeyProtect.
|
||||||
|
// It is expected that one of these is created per KeyProtect service instance/credential pair.
|
||||||
|
type Client struct {
|
||||||
|
URL *url.URL
|
||||||
|
HttpClient http.Client
|
||||||
|
Dump Dump
|
||||||
|
Config ClientConfig
|
||||||
|
Logger Logger
|
||||||
|
|
||||||
|
tokenSource iam.TokenSource
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates and returns a Client without logging.
|
||||||
|
func New(config ClientConfig, transport http.RoundTripper) (*Client, error) {
|
||||||
|
return NewWithLogger(config, transport, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWithLogger creates and returns a Client with logging. The
|
||||||
|
// error value will be non-nil if the config is invalid.
|
||||||
|
func NewWithLogger(config ClientConfig, transport http.RoundTripper, logger Logger) (*Client, error) {
|
||||||
|
|
||||||
|
if transport == nil {
|
||||||
|
transport = DefaultTransport()
|
||||||
|
}
|
||||||
|
|
||||||
|
if logger == nil {
|
||||||
|
logger = NewLogger(func(args ...interface{}) {
|
||||||
|
fmt.Println(args...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Verbose > len(dumpers)-1 || config.Verbose < 0 {
|
||||||
|
return nil, errors.New("verbose value is out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Timeout == 0 {
|
||||||
|
config.Timeout = defaultTimeout
|
||||||
|
}
|
||||||
|
keysURL := fmt.Sprintf("%s/api/v2/", config.BaseURL)
|
||||||
|
|
||||||
|
u, err := url.Parse(keysURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := iam.CredentialFromAPIKey(config.APIKey)
|
||||||
|
|
||||||
|
if config.TokenURL != "" {
|
||||||
|
ts.TokenURL = config.TokenURL
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &Client{
|
||||||
|
URL: u,
|
||||||
|
HttpClient: http.Client{
|
||||||
|
Timeout: time.Duration(config.Timeout * float64(time.Second)),
|
||||||
|
Transport: transport,
|
||||||
|
},
|
||||||
|
Dump: dumpers[config.Verbose],
|
||||||
|
Config: config,
|
||||||
|
Logger: logger,
|
||||||
|
tokenSource: ts,
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) newRequest(method, path string, body interface{}) (*http.Request, error) {
|
||||||
|
|
||||||
|
u, err := c.URL.Parse(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var reqBody []byte
|
||||||
|
var buf io.Reader
|
||||||
|
|
||||||
|
if body != nil {
|
||||||
|
reqBody, err = json.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
buf = bytes.NewBuffer(reqBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
request, err := http.NewRequest(method, u.String(), buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Header.Set("accept", "application/json")
|
||||||
|
|
||||||
|
return request, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type reason struct {
|
||||||
|
Code string
|
||||||
|
Message string
|
||||||
|
Status int
|
||||||
|
MoreInfo string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r reason) String() string {
|
||||||
|
if r.MoreInfo != "" {
|
||||||
|
return fmt.Sprintf("%s: %s - FOR_MORE_INFO_REFER: %s", r.Code, r.Message, r.MoreInfo)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s: %s", r.Code, r.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
URL string // URL of request that resulted in this error
|
||||||
|
StatusCode int // HTTP error code from KeyProtect service
|
||||||
|
Message string // error message from KeyProtect service
|
||||||
|
BodyContent []byte // raw body content if more inspection is needed
|
||||||
|
CorrelationID string // string value of a UUID that uniquely identifies the request to KeyProtect
|
||||||
|
Reasons []reason // collection of reason types containing detailed error messages
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns correlation id and error message string
|
||||||
|
func (e Error) Error() string {
|
||||||
|
var extraVars string
|
||||||
|
if e.Reasons != nil && len(e.Reasons) > 0 {
|
||||||
|
extraVars = fmt.Sprintf(", reasons='%s'", e.Reasons)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("kp.Error: correlation_id='%v', msg='%s'%s", e.CorrelationID, e.Message, extraVars)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLError wraps an error from client.do() calls with a correlation ID from KeyProtect
|
||||||
|
type URLError struct {
|
||||||
|
Err error
|
||||||
|
CorrelationID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e URLError) Error() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"error during request to KeyProtect correlation_id='%s': %s", e.CorrelationID, e.Err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) do(ctx context.Context, req *http.Request, res interface{}) (*http.Response, error) {
|
||||||
|
|
||||||
|
acccesToken, err := c.getAccessToken(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve the correlation id from the context. If not present, then a UUID will be
|
||||||
|
// generated for the correlation ID and feed it into the request
|
||||||
|
// KeyProtect will use this when it is set on a request header rather than generating its
|
||||||
|
// own inside the service
|
||||||
|
// if not present, we generate our own here because a connection error might actually
|
||||||
|
// mean the request doesn't make it server side, so having a correlation ID locally helps
|
||||||
|
// us know that when comparing with server side logs.
|
||||||
|
corrID := c.getCorrelationID(ctx)
|
||||||
|
|
||||||
|
req.Header.Set("bluemix-instance", c.Config.InstanceID)
|
||||||
|
req.Header.Set("authorization", acccesToken)
|
||||||
|
req.Header.Set("correlation-id", corrID)
|
||||||
|
|
||||||
|
if c.Config.KeyRing != "" {
|
||||||
|
req.Header.Set("x-kms-key-ring", c.Config.KeyRing)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set request up to be retryable on 500-level http codes and client errors
|
||||||
|
retryableClient := getRetryableClient(&c.HttpClient)
|
||||||
|
retryableRequest, err := rhttp.FromRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := retryableClient.Do(retryableRequest.WithContext(ctx))
|
||||||
|
if err != nil {
|
||||||
|
return nil, &URLError{err, corrID}
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
resBody, err := ioutil.ReadAll(response.Body)
|
||||||
|
redact := []string{c.Config.APIKey, req.Header.Get("authorization")}
|
||||||
|
c.Dump(req, response, []byte{}, resBody, c.Logger, redact)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type KPErrorMsg struct {
|
||||||
|
Message string `json:"errorMsg,omitempty"`
|
||||||
|
Reasons []reason
|
||||||
|
}
|
||||||
|
|
||||||
|
type KPError struct {
|
||||||
|
Resources []KPErrorMsg `json:"resources,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
switch response.StatusCode {
|
||||||
|
case http.StatusCreated:
|
||||||
|
if len(resBody) != 0 {
|
||||||
|
if err := json.Unmarshal(resBody, res); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case http.StatusOK:
|
||||||
|
if err := json.Unmarshal(resBody, res); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
case http.StatusNoContent:
|
||||||
|
default:
|
||||||
|
errMessage := string(resBody)
|
||||||
|
var reasons []reason
|
||||||
|
|
||||||
|
if strings.Contains(string(resBody), "errorMsg") {
|
||||||
|
kperr := KPError{}
|
||||||
|
json.Unmarshal(resBody, &kperr)
|
||||||
|
if len(kperr.Resources) > 0 && len(kperr.Resources[0].Message) > 0 {
|
||||||
|
errMessage = kperr.Resources[0].Message
|
||||||
|
reasons = kperr.Resources[0].Reasons
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, &Error{
|
||||||
|
URL: response.Request.URL.String(),
|
||||||
|
StatusCode: response.StatusCode,
|
||||||
|
Message: errMessage,
|
||||||
|
BodyContent: resBody,
|
||||||
|
CorrelationID: corrID,
|
||||||
|
Reasons: reasons,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRetryableClient returns a fully configured retryable HTTP client
|
||||||
|
func getRetryableClient(client *http.Client) *rhttp.Client {
|
||||||
|
// build base client with the library defaults and override as neeeded
|
||||||
|
rc := rhttp.NewClient()
|
||||||
|
rc.Logger = nil
|
||||||
|
rc.HTTPClient = client
|
||||||
|
rc.RetryWaitMax = RetryWaitMax
|
||||||
|
rc.RetryMax = RetryMax
|
||||||
|
rc.CheckRetry = kpCheckRetry
|
||||||
|
rc.ErrorHandler = rhttp.PassthroughErrorHandler
|
||||||
|
return rc
|
||||||
|
}
|
||||||
|
|
||||||
|
// kpCheckRetry will retry on connection errors, server errors, and 429s (rate limit)
|
||||||
|
func kpCheckRetry(ctx context.Context, resp *http.Response, err error) (bool, error) {
|
||||||
|
// do not retry on context.Canceled or context.DeadlineExceeded
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return false, ctx.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
// Retry on connection errors, 500+ errors (except 501 - not implemented), and 429 - too many requests
|
||||||
|
if resp.StatusCode == 0 || resp.StatusCode == 429 || (resp.StatusCode >= 500 && resp.StatusCode != 501) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextKey provides a type to auth context keys.
|
||||||
|
type ContextKey int
|
||||||
|
|
||||||
|
// NewContextWithAuth ...
|
||||||
|
func NewContextWithAuth(parent context.Context, auth string) context.Context {
|
||||||
|
return context.WithValue(parent, authContextKey, auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getAccessToken returns the auth context from the given Context, or
|
||||||
|
// calls to the IAMTokenSource to retrieve an auth token.
|
||||||
|
func (c *Client) getAccessToken(ctx context.Context) (string, error) {
|
||||||
|
if ctx.Value(authContextKey) != nil {
|
||||||
|
return ctx.Value(authContextKey).(string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.Config.Authorization) > 0 {
|
||||||
|
return c.Config.Authorization, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := c.tokenSource.Token()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s %s", token.TokenType, token.AccessToken), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getCorrelationId returns the correlation ID value from the given Context, or
|
||||||
|
// returns a new UUID if not present
|
||||||
|
func (c *Client) getCorrelationID(ctx context.Context) string {
|
||||||
|
corrID := GetCorrelationID(ctx)
|
||||||
|
if corrID == nil {
|
||||||
|
return uuid.New().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
return corrID.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContextWithCorrelationID retuns a context containing the UUID
|
||||||
|
func NewContextWithCorrelationID(ctx context.Context, uuid *uuid.UUID) context.Context {
|
||||||
|
return context.WithValue(ctx, cidCtxKey, uuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCorrelationID returns the correlation ID from the context
|
||||||
|
func GetCorrelationID(ctx context.Context) *uuid.UUID {
|
||||||
|
if id := ctx.Value(cidCtxKey); id != nil {
|
||||||
|
return id.(*uuid.UUID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c ctxKey) String() string {
|
||||||
|
return string(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logger writes when called.
|
||||||
|
type Logger interface {
|
||||||
|
Info(...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type logger struct {
|
||||||
|
writer func(...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) Info(args ...interface{}) {
|
||||||
|
l.writer(args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogger(writer func(...interface{})) Logger {
|
||||||
|
return &logger{writer: writer}
|
||||||
|
}
|
||||||
|
|
||||||
|
var dumpers = []Dump{dumpNone, dumpBodyOnly, dumpAll, dumpFailOnly, dumpAllNoRedact}
|
||||||
|
|
||||||
|
// Dump writes various parts of an HTTP request and an HTTP response.
|
||||||
|
type Dump func(*http.Request, *http.Response, []byte, []byte, Logger, []string)
|
||||||
|
|
||||||
|
// Redact replaces various pieces of output.
|
||||||
|
type Redact func(string, []string) string
|
||||||
|
|
||||||
|
// dumpFailOnly calls dumpAll when the HTTP response isn't 200 (ok),
|
||||||
|
// 201 (created), or 204 (no content).
|
||||||
|
func dumpFailOnly(req *http.Request, rsp *http.Response, reqBody, resBody []byte, log Logger, redactStrings []string) {
|
||||||
|
switch rsp.StatusCode {
|
||||||
|
case http.StatusOK, http.StatusCreated, http.StatusNoContent:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dumpAll(req, rsp, reqBody, resBody, log, redactStrings)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpAll dumps the HTTP request and the HTTP response body.
|
||||||
|
func dumpAll(req *http.Request, rsp *http.Response, reqBody, resBody []byte, log Logger, redactStrings []string) {
|
||||||
|
dumpRequest(req, rsp, log, redactStrings, redact)
|
||||||
|
dumpBody(reqBody, resBody, log, redactStrings, redact)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpAllNoRedact dumps the HTTP request and HTTP response body without redaction.
|
||||||
|
func dumpAllNoRedact(req *http.Request, rsp *http.Response, reqBody, resBody []byte, log Logger, redactStrings []string) {
|
||||||
|
dumpRequest(req, rsp, log, redactStrings, noredact)
|
||||||
|
dumpBody(reqBody, resBody, log, redactStrings, noredact)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpBodyOnly dumps the HTTP response body.
|
||||||
|
func dumpBodyOnly(req *http.Request, rsp *http.Response, reqBody, resBody []byte, log Logger, redactStrings []string) {
|
||||||
|
dumpBody(reqBody, resBody, log, redactStrings, redact)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpNone does nothing.
|
||||||
|
func dumpNone(req *http.Request, rsp *http.Response, reqBody, resBody []byte, log Logger, redactStrings []string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpRequest dumps the HTTP request.
|
||||||
|
func dumpRequest(req *http.Request, rsp *http.Response, log Logger, redactStrings []string, redact Redact) {
|
||||||
|
// log.Info(redact(fmt.Sprint(req), redactStrings))
|
||||||
|
// log.Info(redact(fmt.Sprint(rsp), redactStrings))
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpBody dumps the HTTP response body with redactions.
|
||||||
|
func dumpBody(reqBody, resBody []byte, log Logger, redactStrings []string, redact Redact) {
|
||||||
|
// log.Info(string(redact(string(reqBody), redactStrings)))
|
||||||
|
// Redact the access token and refresh token if it shows up in the reponnse body. This will happen
|
||||||
|
// when using an API Key
|
||||||
|
var auth iam.Token
|
||||||
|
if strings.Contains(string(resBody), "access_token") {
|
||||||
|
err := json.Unmarshal(resBody, &auth)
|
||||||
|
if err != nil {
|
||||||
|
log.Info(err)
|
||||||
|
}
|
||||||
|
redactStrings = append(redactStrings, auth.AccessToken)
|
||||||
|
redactStrings = append(redactStrings, auth.RefreshToken)
|
||||||
|
}
|
||||||
|
// log.Info(string(redact(string(resBody), redactStrings)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// redact replaces substrings within the given string.
|
||||||
|
func redact(s string, redactStrings []string) string {
|
||||||
|
if len(redactStrings) < 1 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
var a []string
|
||||||
|
for _, s1 := range redactStrings {
|
||||||
|
if s1 != "" {
|
||||||
|
a = append(a, s1)
|
||||||
|
a = append(a, "***Value redacted***")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r := strings.NewReplacer(a...)
|
||||||
|
return r.Replace(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// noredact does not perform redaction, and returns the given string.
|
||||||
|
func noredact(s string, redactStrings []string) string {
|
||||||
|
return s
|
||||||
|
}
|
317
vendor/github.com/IBM/keyprotect-go-client/policy.go
generated
vendored
Normal file
317
vendor/github.com/IBM/keyprotect-go-client/policy.go
generated
vendored
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
// Copyright 2020 IBM Corp.
|
||||||
|
//
|
||||||
|
// 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 kp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
policyType = "application/vnd.ibm.kms.policy+json"
|
||||||
|
|
||||||
|
RotationPolicy = "rotation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Policy represents a policy as returned by the KP API.
|
||||||
|
type Policy struct {
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
CreatedBy string `json:"createdBy,omitempty"`
|
||||||
|
CreatedAt *time.Time `json:"creationDate,omitempty"`
|
||||||
|
CRN string `json:"crn,omitempty"`
|
||||||
|
UpdatedAt *time.Time `json:"lastUpdateDate,omitempty"`
|
||||||
|
UpdatedBy string `json:"updatedBy,omitempty"`
|
||||||
|
Rotation *Rotation `json:"rotation,omitempty"`
|
||||||
|
DualAuth *DualAuth `json:"dualAuthDelete,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Rotation struct {
|
||||||
|
Interval int `json:"interval_month,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DualAuth struct {
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PoliciesMetadata represents the metadata of a collection of keys.
|
||||||
|
type PoliciesMetadata struct {
|
||||||
|
CollectionType string `json:"collectionType"`
|
||||||
|
NumberOfPolicies int `json:"collectionTotal"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Policies represents a collection of Policies.
|
||||||
|
type Policies struct {
|
||||||
|
Metadata PoliciesMetadata `json:"metadata"`
|
||||||
|
Policies []Policy `json:"resources"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPolicy retrieves a policy by Key ID. This function is
|
||||||
|
// deprecated, as it only returns one policy and does not let you
|
||||||
|
// select which policy set it will return. It is kept for backward
|
||||||
|
// compatibility on keys with only one rotation policy. Please update
|
||||||
|
// to use the new GetPolicies or Get<type>Policy functions.
|
||||||
|
func (c *Client) GetPolicy(ctx context.Context, id string) (*Policy, error) {
|
||||||
|
policyresponse := Policies{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("GET", fmt.Sprintf("keys/%s/policies", id), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyresponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPolicy updates a policy resource by specifying the ID of the key and
|
||||||
|
// the rotation interval needed. This function is deprecated as it will only
|
||||||
|
// let you set key rotation policies. To set dual auth and other newer policies
|
||||||
|
// on a key, please use the new SetPolicies of Set<type>Policy functions.
|
||||||
|
func (c *Client) SetPolicy(ctx context.Context, id string, prefer PreferReturn, rotationInterval int) (*Policy, error) {
|
||||||
|
|
||||||
|
policy := Policy{
|
||||||
|
Type: policyType,
|
||||||
|
Rotation: &Rotation{
|
||||||
|
Interval: rotationInterval,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := Policies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: 1,
|
||||||
|
},
|
||||||
|
Policies: []Policy{policy},
|
||||||
|
}
|
||||||
|
|
||||||
|
policyresponse := Policies{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("PUT", fmt.Sprintf("keys/%s/policies", id), &policyRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Prefer", preferHeaders[prefer])
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyresponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPolicies retrieves all policies details associated with a Key ID.
|
||||||
|
func (c *Client) GetPolicies(ctx context.Context, id string) ([]Policy, error) {
|
||||||
|
policyresponse := Policies{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("GET", fmt.Sprintf("keys/%s/policies", id), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return policyresponse.Policies, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getPolicy(ctx context.Context, id, policyType string, policyresponse *Policies) error {
|
||||||
|
req, err := c.newRequest("GET", fmt.Sprintf("keys/%s/policies", id), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("policy", policyType)
|
||||||
|
req.URL.RawQuery = v.Encode()
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRotationPolivy method retrieves rotation policy details of a key
|
||||||
|
// For more information can refet the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-set-rotation-policy#view-rotation-policy-api
|
||||||
|
func (c *Client) GetRotationPolicy(ctx context.Context, id string) (*Policy, error) {
|
||||||
|
policyresponse := Policies{}
|
||||||
|
|
||||||
|
err := c.getPolicy(ctx, id, RotationPolicy, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyresponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyresponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDualAuthDeletePolicy method retrieves dual auth delete policy details of a key
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-set-dual-auth-key-policy#view-dual-auth-key-policy-api
|
||||||
|
func (c *Client) GetDualAuthDeletePolicy(ctx context.Context, id string) (*Policy, error) {
|
||||||
|
policyresponse := Policies{}
|
||||||
|
|
||||||
|
err := c.getPolicy(ctx, id, DualAuthDelete, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyresponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyresponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) setPolicy(ctx context.Context, id, policyType string, policyRequest Policies) (*Policies, error) {
|
||||||
|
policyresponse := Policies{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("PUT", fmt.Sprintf("keys/%s/policies", id), &policyRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("policy", policyType)
|
||||||
|
req.URL.RawQuery = v.Encode()
|
||||||
|
|
||||||
|
_, err = c.do(ctx, req, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &policyresponse, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRotationPolicy updates the rotation policy associated with a key by specifying key ID and rotation interval.
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-set-rotation-policy#update-rotation-policy-api
|
||||||
|
func (c *Client) SetRotationPolicy(ctx context.Context, id string, rotationInterval int) (*Policy, error) {
|
||||||
|
policy := Policy{
|
||||||
|
Type: policyType,
|
||||||
|
Rotation: &Rotation{
|
||||||
|
Interval: rotationInterval,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := Policies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: 1,
|
||||||
|
},
|
||||||
|
Policies: []Policy{policy},
|
||||||
|
}
|
||||||
|
|
||||||
|
policyresponse, err := c.setPolicy(ctx, id, RotationPolicy, policyRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyresponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyresponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDualAuthDeletePolicy updates the dual auth delete policy by passing the key ID and enable detail
|
||||||
|
// For more information can refer the Key Protect docs in the link below:
|
||||||
|
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-set-dual-auth-key-policy#create-dual-auth-key-policy-api
|
||||||
|
func (c *Client) SetDualAuthDeletePolicy(ctx context.Context, id string, enabled bool) (*Policy, error) {
|
||||||
|
policy := Policy{
|
||||||
|
Type: policyType,
|
||||||
|
DualAuth: &DualAuth{
|
||||||
|
Enabled: &enabled,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := Policies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: 1,
|
||||||
|
},
|
||||||
|
Policies: []Policy{policy},
|
||||||
|
}
|
||||||
|
|
||||||
|
policyresponse, err := c.setPolicy(ctx, id, DualAuthDelete, policyRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(policyresponse.Policies) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &policyresponse.Policies[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPolicies updates all policies of the key or a single policy by passing key ID.
|
||||||
|
// To set rotation policy for the key pass the setRotationPolicy parameter as true and set the rotationInterval detail.
|
||||||
|
// To set dual auth delete policy for the key pass the setDualAuthDeletePolicy parameter as true and set the dualAuthEnable detail.
|
||||||
|
// Both the policies can be set or either of the policies can be set.
|
||||||
|
func (c *Client) SetPolicies(ctx context.Context, id string, setRotationPolicy bool, rotationInterval int, setDualAuthDeletePolicy, dualAuthEnable bool) ([]Policy, error) {
|
||||||
|
policies := []Policy{}
|
||||||
|
if setRotationPolicy {
|
||||||
|
rotationPolicy := Policy{
|
||||||
|
Type: policyType,
|
||||||
|
Rotation: &Rotation{
|
||||||
|
Interval: rotationInterval,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
policies = append(policies, rotationPolicy)
|
||||||
|
}
|
||||||
|
if setDualAuthDeletePolicy {
|
||||||
|
dulaAuthPolicy := Policy{
|
||||||
|
Type: policyType,
|
||||||
|
DualAuth: &DualAuth{
|
||||||
|
Enabled: &dualAuthEnable,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
policies = append(policies, dulaAuthPolicy)
|
||||||
|
}
|
||||||
|
|
||||||
|
policyRequest := Policies{
|
||||||
|
Metadata: PoliciesMetadata{
|
||||||
|
CollectionType: policyType,
|
||||||
|
NumberOfPolicies: len(policies),
|
||||||
|
},
|
||||||
|
Policies: policies,
|
||||||
|
}
|
||||||
|
|
||||||
|
policyresponse := Policies{}
|
||||||
|
|
||||||
|
req, err := c.newRequest("PUT", fmt.Sprintf("keys/%s/policies", id), &policyRequest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, err = c.do(ctx, req, &policyresponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return policyresponse.Policies, nil
|
||||||
|
}
|
69
vendor/github.com/IBM/keyprotect-go-client/registrations.go
generated
vendored
Normal file
69
vendor/github.com/IBM/keyprotect-go-client/registrations.go
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright 2020 IBM Corp.
|
||||||
|
//
|
||||||
|
// 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 kp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Registration represents the registration as returned by KP API
|
||||||
|
type Registration struct {
|
||||||
|
KeyID string `json:"keyId,omitempty"`
|
||||||
|
ResourceCrn string `json:"resourceCrn,omitempty"`
|
||||||
|
CreatedBy string `json:"createdBy,omitempty"`
|
||||||
|
CreationDate *time.Time `json:"creationDate,omitempty"`
|
||||||
|
UpdatedBy string `json:"updatedBy,omitempty"`
|
||||||
|
LastUpdateDate *time.Time `json:"lastUpdated,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
PreventKeyDeletion bool `json:"preventKeyDeletion,omitempty"`
|
||||||
|
KeyVersion KeyVersion `json:"keyVersion,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type registrations struct {
|
||||||
|
Metadata KeysMetadata `json:"metadata"`
|
||||||
|
Registrations []Registration `json:"resources"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListRegistrations retrieves a collection of registrations
|
||||||
|
func (c *Client) ListRegistrations(ctx context.Context, keyId, crn string) (*registrations, error) {
|
||||||
|
registrationAPI := ""
|
||||||
|
if keyId != "" {
|
||||||
|
registrationAPI = fmt.Sprintf("keys/%s/registrations", keyId)
|
||||||
|
} else {
|
||||||
|
registrationAPI = "keys/registrations"
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := c.newRequest("GET", registrationAPI, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if crn != "" {
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("urlEncodedResourceCRNQuery", crn)
|
||||||
|
req.URL.RawQuery = v.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
regs := registrations{}
|
||||||
|
_, err = c.do(ctx, req, ®s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ®s, nil
|
||||||
|
}
|
17
vendor/github.com/armon/go-metrics/go.mod
generated
vendored
17
vendor/github.com/armon/go-metrics/go.mod
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
module github.com/armon/go-metrics
|
|
||||||
|
|
||||||
go 1.12
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible
|
|
||||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible
|
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3 // indirect
|
|
||||||
github.com/golang/protobuf v1.3.2
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0
|
|
||||||
github.com/hashicorp/go-retryablehttp v0.5.3 // indirect
|
|
||||||
github.com/pascaldekloe/goe v0.1.0
|
|
||||||
github.com/prometheus/client_golang v1.4.0
|
|
||||||
github.com/prometheus/client_model v0.2.0
|
|
||||||
github.com/prometheus/common v0.9.1
|
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect
|
|
||||||
)
|
|
125
vendor/github.com/armon/go-metrics/go.sum
generated
vendored
125
vendor/github.com/armon/go-metrics/go.sum
generated
vendored
@ -1,125 +0,0 @@
|
|||||||
github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4=
|
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY=
|
|
||||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA=
|
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
|
||||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
|
||||||
github.com/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s=
|
|
||||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
||||||
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/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
|
||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
|
||||||
github.com/prometheus/client_golang v1.4.0 h1:YVIb/fVcOTMSqtqZWSKnHpSLBxu8DKgxq8z6RuBZwqI=
|
|
||||||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
|
||||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
|
|
||||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
|
||||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=
|
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
1
vendor/github.com/armon/go-radix/go.mod
generated
vendored
1
vendor/github.com/armon/go-radix/go.mod
generated
vendored
@ -1 +0,0 @@
|
|||||||
module github.com/armon/go-radix
|
|
3
vendor/github.com/bits-and-blooms/bitset/go.mod
generated
vendored
3
vendor/github.com/bits-and-blooms/bitset/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
module github.com/bits-and-blooms/bitset
|
|
||||||
|
|
||||||
go 1.14
|
|
0
vendor/github.com/bits-and-blooms/bitset/go.sum
generated
vendored
0
vendor/github.com/bits-and-blooms/bitset/go.sum
generated
vendored
3
vendor/github.com/cenkalti/backoff/v3/go.mod
generated
vendored
3
vendor/github.com/cenkalti/backoff/v3/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
module github.com/cenkalti/backoff/v3
|
|
||||||
|
|
||||||
go 1.12
|
|
3
vendor/github.com/cespare/xxhash/v2/go.mod
generated
vendored
3
vendor/github.com/cespare/xxhash/v2/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
module github.com/cespare/xxhash/v2
|
|
||||||
|
|
||||||
go 1.11
|
|
0
vendor/github.com/cespare/xxhash/v2/go.sum
generated
vendored
0
vendor/github.com/cespare/xxhash/v2/go.sum
generated
vendored
6
vendor/github.com/evanphx/json-patch/.gitignore
generated
vendored
Normal file
6
vendor/github.com/evanphx/json-patch/.gitignore
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# editor and IDE paraphernalia
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# macOS paraphernalia
|
||||||
|
.DS_Store
|
63
vendor/github.com/evanphx/json-patch/patch.go
generated
vendored
63
vendor/github.com/evanphx/json-patch/patch.go
generated
vendored
@ -412,6 +412,17 @@ func (d *partialArray) set(key string, val *lazyNode) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if idx < 0 {
|
||||||
|
if !SupportNegativeIndices {
|
||||||
|
return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||||
|
}
|
||||||
|
if idx < -len(*d) {
|
||||||
|
return errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||||
|
}
|
||||||
|
idx += len(*d)
|
||||||
|
}
|
||||||
|
|
||||||
(*d)[idx] = val
|
(*d)[idx] = val
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -462,6 +473,16 @@ func (d *partialArray) get(key string) (*lazyNode, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if idx < 0 {
|
||||||
|
if !SupportNegativeIndices {
|
||||||
|
return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||||
|
}
|
||||||
|
if idx < -len(*d) {
|
||||||
|
return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||||
|
}
|
||||||
|
idx += len(*d)
|
||||||
|
}
|
||||||
|
|
||||||
if idx >= len(*d) {
|
if idx >= len(*d) {
|
||||||
return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
return nil, errors.Wrapf(ErrInvalidIndex, "Unable to access invalid index: %d", idx)
|
||||||
}
|
}
|
||||||
@ -547,6 +568,29 @@ func (p Patch) replace(doc *container, op Operation) error {
|
|||||||
return errors.Wrapf(err, "replace operation failed to decode path")
|
return errors.Wrapf(err, "replace operation failed to decode path")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if path == "" {
|
||||||
|
val := op.value()
|
||||||
|
|
||||||
|
if val.which == eRaw {
|
||||||
|
if !val.tryDoc() {
|
||||||
|
if !val.tryAry() {
|
||||||
|
return errors.Wrapf(err, "replace operation value must be object or array")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch val.which {
|
||||||
|
case eAry:
|
||||||
|
*doc = &val.ary
|
||||||
|
case eDoc:
|
||||||
|
*doc = &val.doc
|
||||||
|
case eRaw:
|
||||||
|
return errors.Wrapf(err, "replace operation hit impossible case")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
con, key := findObject(doc, path)
|
con, key := findObject(doc, path)
|
||||||
|
|
||||||
if con == nil {
|
if con == nil {
|
||||||
@ -613,6 +657,25 @@ func (p Patch) test(doc *container, op Operation) error {
|
|||||||
return errors.Wrapf(err, "test operation failed to decode path")
|
return errors.Wrapf(err, "test operation failed to decode path")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if path == "" {
|
||||||
|
var self lazyNode
|
||||||
|
|
||||||
|
switch sv := (*doc).(type) {
|
||||||
|
case *partialDoc:
|
||||||
|
self.doc = *sv
|
||||||
|
self.which = eDoc
|
||||||
|
case *partialArray:
|
||||||
|
self.ary = *sv
|
||||||
|
self.which = eAry
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.equal(op.value()) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.Wrapf(ErrTestFailed, "testing value %s failed", path)
|
||||||
|
}
|
||||||
|
|
||||||
con, key := findObject(doc, path)
|
con, key := findObject(doc, path)
|
||||||
|
|
||||||
if con == nil {
|
if con == nil {
|
||||||
|
8
vendor/github.com/fatih/color/go.mod
generated
vendored
8
vendor/github.com/fatih/color/go.mod
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
module github.com/fatih/color
|
|
||||||
|
|
||||||
go 1.13
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/mattn/go-colorable v0.1.4
|
|
||||||
github.com/mattn/go-isatty v0.0.11
|
|
||||||
)
|
|
8
vendor/github.com/fatih/color/go.sum
generated
vendored
8
vendor/github.com/fatih/color/go.sum
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
|
||||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
3
vendor/github.com/felixge/httpsnoop/go.mod
generated
vendored
3
vendor/github.com/felixge/httpsnoop/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
module github.com/felixge/httpsnoop
|
|
||||||
|
|
||||||
go 1.13
|
|
2
vendor/github.com/fsnotify/fsnotify/.mailmap
generated
vendored
Normal file
2
vendor/github.com/fsnotify/fsnotify/.mailmap
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Chris Howey <howeyc@gmail.com> <chris@howey.me>
|
||||||
|
Nathan Youngman <git@nathany.com> <4566+nathany@users.noreply.github.com>
|
36
vendor/github.com/fsnotify/fsnotify/.travis.yml
generated
vendored
36
vendor/github.com/fsnotify/fsnotify/.travis.yml
generated
vendored
@ -1,36 +0,0 @@
|
|||||||
sudo: false
|
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- "stable"
|
|
||||||
- "1.11.x"
|
|
||||||
- "1.10.x"
|
|
||||||
- "1.9.x"
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- go: "stable"
|
|
||||||
env: GOLINT=true
|
|
||||||
allow_failures:
|
|
||||||
- go: tip
|
|
||||||
fast_finish: true
|
|
||||||
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- if [ ! -z "${GOLINT}" ]; then go get -u golang.org/x/lint/golint; fi
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test --race ./...
|
|
||||||
|
|
||||||
after_script:
|
|
||||||
- test -z "$(gofmt -s -l -w . | tee /dev/stderr)"
|
|
||||||
- if [ ! -z "${GOLINT}" ]; then echo running golint; golint --set_exit_status ./...; else echo skipping golint; fi
|
|
||||||
- go vet ./...
|
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
- windows
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
email: false
|
|
16
vendor/github.com/fsnotify/fsnotify/AUTHORS
generated
vendored
16
vendor/github.com/fsnotify/fsnotify/AUTHORS
generated
vendored
@ -4,35 +4,44 @@
|
|||||||
|
|
||||||
# You can update this list using the following command:
|
# You can update this list using the following command:
|
||||||
#
|
#
|
||||||
# $ git shortlog -se | awk '{print $2 " " $3 " " $4}'
|
# $ (head -n10 AUTHORS && git shortlog -se | sed -E 's/^\s+[0-9]+\t//') | tee AUTHORS
|
||||||
|
|
||||||
# Please keep the list sorted.
|
# Please keep the list sorted.
|
||||||
|
|
||||||
Aaron L <aaron@bettercoder.net>
|
Aaron L <aaron@bettercoder.net>
|
||||||
Adrien Bustany <adrien@bustany.org>
|
Adrien Bustany <adrien@bustany.org>
|
||||||
|
Alexey Kazakov <alkazako@redhat.com>
|
||||||
Amit Krishnan <amit.krishnan@oracle.com>
|
Amit Krishnan <amit.krishnan@oracle.com>
|
||||||
Anmol Sethi <me@anmol.io>
|
Anmol Sethi <me@anmol.io>
|
||||||
Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
|
Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
|
||||||
|
Brian Goff <cpuguy83@gmail.com>
|
||||||
Bruno Bigras <bigras.bruno@gmail.com>
|
Bruno Bigras <bigras.bruno@gmail.com>
|
||||||
Caleb Spare <cespare@gmail.com>
|
Caleb Spare <cespare@gmail.com>
|
||||||
Case Nelson <case@teammating.com>
|
Case Nelson <case@teammating.com>
|
||||||
Chris Howey <chris@howey.me> <howeyc@gmail.com>
|
Chris Howey <howeyc@gmail.com>
|
||||||
Christoffer Buchholz <christoffer.buchholz@gmail.com>
|
Christoffer Buchholz <christoffer.buchholz@gmail.com>
|
||||||
Daniel Wagner-Hall <dawagner@gmail.com>
|
Daniel Wagner-Hall <dawagner@gmail.com>
|
||||||
Dave Cheney <dave@cheney.net>
|
Dave Cheney <dave@cheney.net>
|
||||||
|
Eric Lin <linxiulei@gmail.com>
|
||||||
Evan Phoenix <evan@fallingsnow.net>
|
Evan Phoenix <evan@fallingsnow.net>
|
||||||
Francisco Souza <f@souza.cc>
|
Francisco Souza <f@souza.cc>
|
||||||
|
Gautam Dey <gautam.dey77@gmail.com>
|
||||||
Hari haran <hariharan.uno@gmail.com>
|
Hari haran <hariharan.uno@gmail.com>
|
||||||
John C Barstow
|
Ichinose Shogo <shogo82148@gmail.com>
|
||||||
|
Johannes Ebke <johannes@ebke.org>
|
||||||
|
John C Barstow <jbowtie@amathaine.com>
|
||||||
Kelvin Fo <vmirage@gmail.com>
|
Kelvin Fo <vmirage@gmail.com>
|
||||||
Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp>
|
Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp>
|
||||||
Matt Layher <mdlayher@gmail.com>
|
Matt Layher <mdlayher@gmail.com>
|
||||||
|
Matthias Stone <matthias@bellstone.ca>
|
||||||
Nathan Youngman <git@nathany.com>
|
Nathan Youngman <git@nathany.com>
|
||||||
Nickolai Zeldovich <nickolai@csail.mit.edu>
|
Nickolai Zeldovich <nickolai@csail.mit.edu>
|
||||||
|
Oliver Bristow <evilumbrella+github@gmail.com>
|
||||||
Patrick <patrick@dropbox.com>
|
Patrick <patrick@dropbox.com>
|
||||||
Paul Hammond <paul@paulhammond.org>
|
Paul Hammond <paul@paulhammond.org>
|
||||||
Pawel Knap <pawelknap88@gmail.com>
|
Pawel Knap <pawelknap88@gmail.com>
|
||||||
Pieter Droogendijk <pieter@binky.org.uk>
|
Pieter Droogendijk <pieter@binky.org.uk>
|
||||||
|
Pratik Shinde <pratikshinde320@gmail.com>
|
||||||
Pursuit92 <JoshChase@techpursuit.net>
|
Pursuit92 <JoshChase@techpursuit.net>
|
||||||
Riku Voipio <riku.voipio@linaro.org>
|
Riku Voipio <riku.voipio@linaro.org>
|
||||||
Rob Figueiredo <robfig@gmail.com>
|
Rob Figueiredo <robfig@gmail.com>
|
||||||
@ -41,6 +50,7 @@ Slawek Ligus <root@ooz.ie>
|
|||||||
Soge Zhang <zhssoge@gmail.com>
|
Soge Zhang <zhssoge@gmail.com>
|
||||||
Tiffany Jernigan <tiffany.jernigan@intel.com>
|
Tiffany Jernigan <tiffany.jernigan@intel.com>
|
||||||
Tilak Sharma <tilaks@google.com>
|
Tilak Sharma <tilaks@google.com>
|
||||||
|
Tobias Klauser <tobias.klauser@gmail.com>
|
||||||
Tom Payne <twpayne@gmail.com>
|
Tom Payne <twpayne@gmail.com>
|
||||||
Travis Cline <travis.cline@gmail.com>
|
Travis Cline <travis.cline@gmail.com>
|
||||||
Tudor Golubenco <tudor.g@gmail.com>
|
Tudor Golubenco <tudor.g@gmail.com>
|
||||||
|
116
vendor/github.com/fsnotify/fsnotify/CHANGELOG.md
generated
vendored
116
vendor/github.com/fsnotify/fsnotify/CHANGELOG.md
generated
vendored
@ -1,6 +1,28 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v1.4.7 / 2018-01-09
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.5.1] - 2021-08-24
|
||||||
|
|
||||||
|
* Revert Add AddRaw to not follow symlinks
|
||||||
|
|
||||||
|
## [1.5.0] - 2021-08-20
|
||||||
|
|
||||||
|
* Go: Increase minimum required version to Go 1.12 [#381](https://github.com/fsnotify/fsnotify/pull/381)
|
||||||
|
* Feature: Add AddRaw method which does not follow symlinks when adding a watch [#289](https://github.com/fsnotify/fsnotify/pull/298)
|
||||||
|
* Windows: Follow symlinks by default like on all other systems [#289](https://github.com/fsnotify/fsnotify/pull/289)
|
||||||
|
* CI: Use GitHub Actions for CI and cover go 1.12-1.17
|
||||||
|
[#378](https://github.com/fsnotify/fsnotify/pull/378)
|
||||||
|
[#381](https://github.com/fsnotify/fsnotify/pull/381)
|
||||||
|
[#385](https://github.com/fsnotify/fsnotify/pull/385)
|
||||||
|
* Go 1.14+: Fix unsafe pointer conversion [#325](https://github.com/fsnotify/fsnotify/pull/325)
|
||||||
|
|
||||||
|
## [1.4.7] - 2018-01-09
|
||||||
|
|
||||||
* BSD/macOS: Fix possible deadlock on closing the watcher on kqueue (thanks @nhooyr and @glycerine)
|
* BSD/macOS: Fix possible deadlock on closing the watcher on kqueue (thanks @nhooyr and @glycerine)
|
||||||
* Tests: Fix missing verb on format string (thanks @rchiossi)
|
* Tests: Fix missing verb on format string (thanks @rchiossi)
|
||||||
@ -10,62 +32,62 @@
|
|||||||
* Linux: Properly handle inotify's IN_Q_OVERFLOW event (thanks @zeldovich)
|
* Linux: Properly handle inotify's IN_Q_OVERFLOW event (thanks @zeldovich)
|
||||||
* Docs: replace references to OS X with macOS
|
* Docs: replace references to OS X with macOS
|
||||||
|
|
||||||
## v1.4.2 / 2016-10-10
|
## [1.4.2] - 2016-10-10
|
||||||
|
|
||||||
* Linux: use InotifyInit1 with IN_CLOEXEC to stop leaking a file descriptor to a child process when using fork/exec [#178](https://github.com/fsnotify/fsnotify/pull/178) (thanks @pattyshack)
|
* Linux: use InotifyInit1 with IN_CLOEXEC to stop leaking a file descriptor to a child process when using fork/exec [#178](https://github.com/fsnotify/fsnotify/pull/178) (thanks @pattyshack)
|
||||||
|
|
||||||
## v1.4.1 / 2016-10-04
|
## [1.4.1] - 2016-10-04
|
||||||
|
|
||||||
* Fix flaky inotify stress test on Linux [#177](https://github.com/fsnotify/fsnotify/pull/177) (thanks @pattyshack)
|
* Fix flaky inotify stress test on Linux [#177](https://github.com/fsnotify/fsnotify/pull/177) (thanks @pattyshack)
|
||||||
|
|
||||||
## v1.4.0 / 2016-10-01
|
## [1.4.0] - 2016-10-01
|
||||||
|
|
||||||
* add a String() method to Event.Op [#165](https://github.com/fsnotify/fsnotify/pull/165) (thanks @oozie)
|
* add a String() method to Event.Op [#165](https://github.com/fsnotify/fsnotify/pull/165) (thanks @oozie)
|
||||||
|
|
||||||
## v1.3.1 / 2016-06-28
|
## [1.3.1] - 2016-06-28
|
||||||
|
|
||||||
* Windows: fix for double backslash when watching the root of a drive [#151](https://github.com/fsnotify/fsnotify/issues/151) (thanks @brunoqc)
|
* Windows: fix for double backslash when watching the root of a drive [#151](https://github.com/fsnotify/fsnotify/issues/151) (thanks @brunoqc)
|
||||||
|
|
||||||
## v1.3.0 / 2016-04-19
|
## [1.3.0] - 2016-04-19
|
||||||
|
|
||||||
* Support linux/arm64 by [patching](https://go-review.googlesource.com/#/c/21971/) x/sys/unix and switching to to it from syscall (thanks @suihkulokki) [#135](https://github.com/fsnotify/fsnotify/pull/135)
|
* Support linux/arm64 by [patching](https://go-review.googlesource.com/#/c/21971/) x/sys/unix and switching to to it from syscall (thanks @suihkulokki) [#135](https://github.com/fsnotify/fsnotify/pull/135)
|
||||||
|
|
||||||
## v1.2.10 / 2016-03-02
|
## [1.2.10] - 2016-03-02
|
||||||
|
|
||||||
* Fix golint errors in windows.go [#121](https://github.com/fsnotify/fsnotify/pull/121) (thanks @tiffanyfj)
|
* Fix golint errors in windows.go [#121](https://github.com/fsnotify/fsnotify/pull/121) (thanks @tiffanyfj)
|
||||||
|
|
||||||
## v1.2.9 / 2016-01-13
|
## [1.2.9] - 2016-01-13
|
||||||
|
|
||||||
kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsnotify/pull/111) (thanks @bep)
|
kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsnotify/pull/111) (thanks @bep)
|
||||||
|
|
||||||
## v1.2.8 / 2015-12-17
|
## [1.2.8] - 2015-12-17
|
||||||
|
|
||||||
* kqueue: fix race condition in Close [#105](https://github.com/fsnotify/fsnotify/pull/105) (thanks @djui for reporting the issue and @ppknap for writing a failing test)
|
* kqueue: fix race condition in Close [#105](https://github.com/fsnotify/fsnotify/pull/105) (thanks @djui for reporting the issue and @ppknap for writing a failing test)
|
||||||
* inotify: fix race in test
|
* inotify: fix race in test
|
||||||
* enable race detection for continuous integration (Linux, Mac, Windows)
|
* enable race detection for continuous integration (Linux, Mac, Windows)
|
||||||
|
|
||||||
## v1.2.5 / 2015-10-17
|
## [1.2.5] - 2015-10-17
|
||||||
|
|
||||||
* inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/fsnotify/fsnotify/pull/100) (thanks @suihkulokki)
|
* inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/fsnotify/fsnotify/pull/100) (thanks @suihkulokki)
|
||||||
* inotify: fix path leaks [#73](https://github.com/fsnotify/fsnotify/pull/73) (thanks @chamaken)
|
* inotify: fix path leaks [#73](https://github.com/fsnotify/fsnotify/pull/73) (thanks @chamaken)
|
||||||
* kqueue: watch for rename events on subdirectories [#83](https://github.com/fsnotify/fsnotify/pull/83) (thanks @guotie)
|
* kqueue: watch for rename events on subdirectories [#83](https://github.com/fsnotify/fsnotify/pull/83) (thanks @guotie)
|
||||||
* kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/fsnotify/fsnotify/pull/101) (thanks @illicitonion)
|
* kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/fsnotify/fsnotify/pull/101) (thanks @illicitonion)
|
||||||
|
|
||||||
## v1.2.1 / 2015-10-14
|
## [1.2.1] - 2015-10-14
|
||||||
|
|
||||||
* kqueue: don't watch named pipes [#98](https://github.com/fsnotify/fsnotify/pull/98) (thanks @evanphx)
|
* kqueue: don't watch named pipes [#98](https://github.com/fsnotify/fsnotify/pull/98) (thanks @evanphx)
|
||||||
|
|
||||||
## v1.2.0 / 2015-02-08
|
## [1.2.0] - 2015-02-08
|
||||||
|
|
||||||
* inotify: use epoll to wake up readEvents [#66](https://github.com/fsnotify/fsnotify/pull/66) (thanks @PieterD)
|
* inotify: use epoll to wake up readEvents [#66](https://github.com/fsnotify/fsnotify/pull/66) (thanks @PieterD)
|
||||||
* inotify: closing watcher should now always shut down goroutine [#63](https://github.com/fsnotify/fsnotify/pull/63) (thanks @PieterD)
|
* inotify: closing watcher should now always shut down goroutine [#63](https://github.com/fsnotify/fsnotify/pull/63) (thanks @PieterD)
|
||||||
* kqueue: close kqueue after removing watches, fixes [#59](https://github.com/fsnotify/fsnotify/issues/59)
|
* kqueue: close kqueue after removing watches, fixes [#59](https://github.com/fsnotify/fsnotify/issues/59)
|
||||||
|
|
||||||
## v1.1.1 / 2015-02-05
|
## [1.1.1] - 2015-02-05
|
||||||
|
|
||||||
* inotify: Retry read on EINTR [#61](https://github.com/fsnotify/fsnotify/issues/61) (thanks @PieterD)
|
* inotify: Retry read on EINTR [#61](https://github.com/fsnotify/fsnotify/issues/61) (thanks @PieterD)
|
||||||
|
|
||||||
## v1.1.0 / 2014-12-12
|
## [1.1.0] - 2014-12-12
|
||||||
|
|
||||||
* kqueue: rework internals [#43](https://github.com/fsnotify/fsnotify/pull/43)
|
* kqueue: rework internals [#43](https://github.com/fsnotify/fsnotify/pull/43)
|
||||||
* add low-level functions
|
* add low-level functions
|
||||||
@ -77,22 +99,22 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn
|
|||||||
* kqueue: fix regression in rework causing subdirectories to be watched [#48](https://github.com/fsnotify/fsnotify/issues/48)
|
* kqueue: fix regression in rework causing subdirectories to be watched [#48](https://github.com/fsnotify/fsnotify/issues/48)
|
||||||
* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)
|
* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)
|
||||||
|
|
||||||
## v1.0.4 / 2014-09-07
|
## [1.0.4] - 2014-09-07
|
||||||
|
|
||||||
* kqueue: add dragonfly to the build tags.
|
* kqueue: add dragonfly to the build tags.
|
||||||
* Rename source code files, rearrange code so exported APIs are at the top.
|
* Rename source code files, rearrange code so exported APIs are at the top.
|
||||||
* Add done channel to example code. [#37](https://github.com/fsnotify/fsnotify/pull/37) (thanks @chenyukang)
|
* Add done channel to example code. [#37](https://github.com/fsnotify/fsnotify/pull/37) (thanks @chenyukang)
|
||||||
|
|
||||||
## v1.0.3 / 2014-08-19
|
## [1.0.3] - 2014-08-19
|
||||||
|
|
||||||
* [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/fsnotify/fsnotify/issues/36)
|
* [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/fsnotify/fsnotify/issues/36)
|
||||||
|
|
||||||
## v1.0.2 / 2014-08-17
|
## [1.0.2] - 2014-08-17
|
||||||
|
|
||||||
* [Fix] Missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)
|
* [Fix] Missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)
|
||||||
* [Fix] Make ./path and path equivalent. (thanks @zhsso)
|
* [Fix] Make ./path and path equivalent. (thanks @zhsso)
|
||||||
|
|
||||||
## v1.0.0 / 2014-08-15
|
## [1.0.0] - 2014-08-15
|
||||||
|
|
||||||
* [API] Remove AddWatch on Windows, use Add.
|
* [API] Remove AddWatch on Windows, use Add.
|
||||||
* Improve documentation for exported identifiers. [#30](https://github.com/fsnotify/fsnotify/issues/30)
|
* Improve documentation for exported identifiers. [#30](https://github.com/fsnotify/fsnotify/issues/30)
|
||||||
@ -146,51 +168,51 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn
|
|||||||
* no tests for the current implementation
|
* no tests for the current implementation
|
||||||
* not fully implemented on Windows [#93](https://github.com/howeyc/fsnotify/issues/93#issuecomment-39285195)
|
* not fully implemented on Windows [#93](https://github.com/howeyc/fsnotify/issues/93#issuecomment-39285195)
|
||||||
|
|
||||||
## v0.9.3 / 2014-12-31
|
## [0.9.3] - 2014-12-31
|
||||||
|
|
||||||
* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)
|
* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)
|
||||||
|
|
||||||
## v0.9.2 / 2014-08-17
|
## [0.9.2] - 2014-08-17
|
||||||
|
|
||||||
* [Backport] Fix missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)
|
* [Backport] Fix missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)
|
||||||
|
|
||||||
## v0.9.1 / 2014-06-12
|
## [0.9.1] - 2014-06-12
|
||||||
|
|
||||||
* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98)
|
* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98)
|
||||||
|
|
||||||
## v0.9.0 / 2014-01-17
|
## [0.9.0] - 2014-01-17
|
||||||
|
|
||||||
* IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany)
|
* IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany)
|
||||||
* [Fix] kqueue: fix deadlock [#77][] (thanks @cespare)
|
* [Fix] kqueue: fix deadlock [#77][] (thanks @cespare)
|
||||||
* [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library.
|
* [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library.
|
||||||
|
|
||||||
## v0.8.12 / 2013-11-13
|
## [0.8.12] - 2013-11-13
|
||||||
|
|
||||||
* [API] Remove FD_SET and friends from Linux adapter
|
* [API] Remove FD_SET and friends from Linux adapter
|
||||||
|
|
||||||
## v0.8.11 / 2013-11-02
|
## [0.8.11] - 2013-11-02
|
||||||
|
|
||||||
* [Doc] Add Changelog [#72][] (thanks @nathany)
|
* [Doc] Add Changelog [#72][] (thanks @nathany)
|
||||||
* [Doc] Spotlight and double modify events on macOS [#62][] (reported by @paulhammond)
|
* [Doc] Spotlight and double modify events on macOS [#62][] (reported by @paulhammond)
|
||||||
|
|
||||||
## v0.8.10 / 2013-10-19
|
## [0.8.10] - 2013-10-19
|
||||||
|
|
||||||
* [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott)
|
* [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott)
|
||||||
* [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer)
|
* [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer)
|
||||||
* [Doc] specify OS-specific limits in README (thanks @debrando)
|
* [Doc] specify OS-specific limits in README (thanks @debrando)
|
||||||
|
|
||||||
## v0.8.9 / 2013-09-08
|
## [0.8.9] - 2013-09-08
|
||||||
|
|
||||||
* [Doc] Contributing (thanks @nathany)
|
* [Doc] Contributing (thanks @nathany)
|
||||||
* [Doc] update package path in example code [#63][] (thanks @paulhammond)
|
* [Doc] update package path in example code [#63][] (thanks @paulhammond)
|
||||||
* [Doc] GoCI badge in README (Linux only) [#60][]
|
* [Doc] GoCI badge in README (Linux only) [#60][]
|
||||||
* [Doc] Cross-platform testing with Vagrant [#59][] (thanks @nathany)
|
* [Doc] Cross-platform testing with Vagrant [#59][] (thanks @nathany)
|
||||||
|
|
||||||
## v0.8.8 / 2013-06-17
|
## [0.8.8] - 2013-06-17
|
||||||
|
|
||||||
* [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie)
|
* [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie)
|
||||||
|
|
||||||
## v0.8.7 / 2013-06-03
|
## [0.8.7] - 2013-06-03
|
||||||
|
|
||||||
* [API] Make syscall flags internal
|
* [API] Make syscall flags internal
|
||||||
* [Fix] inotify: ignore event changes
|
* [Fix] inotify: ignore event changes
|
||||||
@ -198,74 +220,74 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn
|
|||||||
* [Fix] tests on Windows
|
* [Fix] tests on Windows
|
||||||
* lower case error messages
|
* lower case error messages
|
||||||
|
|
||||||
## v0.8.6 / 2013-05-23
|
## [0.8.6] - 2013-05-23
|
||||||
|
|
||||||
* kqueue: Use EVT_ONLY flag on Darwin
|
* kqueue: Use EVT_ONLY flag on Darwin
|
||||||
* [Doc] Update README with full example
|
* [Doc] Update README with full example
|
||||||
|
|
||||||
## v0.8.5 / 2013-05-09
|
## [0.8.5] - 2013-05-09
|
||||||
|
|
||||||
* [Fix] inotify: allow monitoring of "broken" symlinks (thanks @tsg)
|
* [Fix] inotify: allow monitoring of "broken" symlinks (thanks @tsg)
|
||||||
|
|
||||||
## v0.8.4 / 2013-04-07
|
## [0.8.4] - 2013-04-07
|
||||||
|
|
||||||
* [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz)
|
* [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz)
|
||||||
|
|
||||||
## v0.8.3 / 2013-03-13
|
## [0.8.3] - 2013-03-13
|
||||||
|
|
||||||
* [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin)
|
* [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin)
|
||||||
* [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin)
|
* [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin)
|
||||||
|
|
||||||
## v0.8.2 / 2013-02-07
|
## [0.8.2] - 2013-02-07
|
||||||
|
|
||||||
* [Doc] add Authors
|
* [Doc] add Authors
|
||||||
* [Fix] fix data races for map access [#29][] (thanks @fsouza)
|
* [Fix] fix data races for map access [#29][] (thanks @fsouza)
|
||||||
|
|
||||||
## v0.8.1 / 2013-01-09
|
## [0.8.1] - 2013-01-09
|
||||||
|
|
||||||
* [Fix] Windows path separators
|
* [Fix] Windows path separators
|
||||||
* [Doc] BSD License
|
* [Doc] BSD License
|
||||||
|
|
||||||
## v0.8.0 / 2012-11-09
|
## [0.8.0] - 2012-11-09
|
||||||
|
|
||||||
* kqueue: directory watching improvements (thanks @vmirage)
|
* kqueue: directory watching improvements (thanks @vmirage)
|
||||||
* inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto)
|
* inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto)
|
||||||
* [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr)
|
* [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr)
|
||||||
|
|
||||||
## v0.7.4 / 2012-10-09
|
## [0.7.4] - 2012-10-09
|
||||||
|
|
||||||
* [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji)
|
* [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji)
|
||||||
* [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig)
|
* [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig)
|
||||||
* [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig)
|
* [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig)
|
||||||
* [Fix] kqueue: modify after recreation of file
|
* [Fix] kqueue: modify after recreation of file
|
||||||
|
|
||||||
## v0.7.3 / 2012-09-27
|
## [0.7.3] - 2012-09-27
|
||||||
|
|
||||||
* [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage)
|
* [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage)
|
||||||
* [Fix] kqueue: no longer get duplicate CREATE events
|
* [Fix] kqueue: no longer get duplicate CREATE events
|
||||||
|
|
||||||
## v0.7.2 / 2012-09-01
|
## [0.7.2] - 2012-09-01
|
||||||
|
|
||||||
* kqueue: events for created directories
|
* kqueue: events for created directories
|
||||||
|
|
||||||
## v0.7.1 / 2012-07-14
|
## [0.7.1] - 2012-07-14
|
||||||
|
|
||||||
* [Fix] for renaming files
|
* [Fix] for renaming files
|
||||||
|
|
||||||
## v0.7.0 / 2012-07-02
|
## [0.7.0] - 2012-07-02
|
||||||
|
|
||||||
* [Feature] FSNotify flags
|
* [Feature] FSNotify flags
|
||||||
* [Fix] inotify: Added file name back to event path
|
* [Fix] inotify: Added file name back to event path
|
||||||
|
|
||||||
## v0.6.0 / 2012-06-06
|
## [0.6.0] - 2012-06-06
|
||||||
|
|
||||||
* kqueue: watch files after directory created (thanks @tmc)
|
* kqueue: watch files after directory created (thanks @tmc)
|
||||||
|
|
||||||
## v0.5.1 / 2012-05-22
|
## [0.5.1] - 2012-05-22
|
||||||
|
|
||||||
* [Fix] inotify: remove all watches before Close()
|
* [Fix] inotify: remove all watches before Close()
|
||||||
|
|
||||||
## v0.5.0 / 2012-05-03
|
## [0.5.0] - 2012-05-03
|
||||||
|
|
||||||
* [API] kqueue: return errors during watch instead of sending over channel
|
* [API] kqueue: return errors during watch instead of sending over channel
|
||||||
* kqueue: match symlink behavior on Linux
|
* kqueue: match symlink behavior on Linux
|
||||||
@ -273,22 +295,22 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn
|
|||||||
* [Fix] kqueue: handle EINTR (reported by @robfig)
|
* [Fix] kqueue: handle EINTR (reported by @robfig)
|
||||||
* [Doc] Godoc example [#1][] (thanks @davecheney)
|
* [Doc] Godoc example [#1][] (thanks @davecheney)
|
||||||
|
|
||||||
## v0.4.0 / 2012-03-30
|
## [0.4.0] - 2012-03-30
|
||||||
|
|
||||||
* Go 1 released: build with go tool
|
* Go 1 released: build with go tool
|
||||||
* [Feature] Windows support using winfsnotify
|
* [Feature] Windows support using winfsnotify
|
||||||
* Windows does not have attribute change notifications
|
* Windows does not have attribute change notifications
|
||||||
* Roll attribute notifications into IsModify
|
* Roll attribute notifications into IsModify
|
||||||
|
|
||||||
## v0.3.0 / 2012-02-19
|
## [0.3.0] - 2012-02-19
|
||||||
|
|
||||||
* kqueue: add files when watch directory
|
* kqueue: add files when watch directory
|
||||||
|
|
||||||
## v0.2.0 / 2011-12-30
|
## [0.2.0] - 2011-12-30
|
||||||
|
|
||||||
* update to latest Go weekly code
|
* update to latest Go weekly code
|
||||||
|
|
||||||
## v0.1.0 / 2011-10-19
|
## [0.1.0] - 2011-10-19
|
||||||
|
|
||||||
* kqueue: add watch on file creation to match inotify
|
* kqueue: add watch on file creation to match inotify
|
||||||
* kqueue: create file event
|
* kqueue: create file event
|
||||||
|
6
vendor/github.com/fsnotify/fsnotify/README.md
generated
vendored
6
vendor/github.com/fsnotify/fsnotify/README.md
generated
vendored
@ -12,9 +12,9 @@ Cross platform: Windows, Linux, BSD and macOS.
|
|||||||
|
|
||||||
| Adapter | OS | Status |
|
| Adapter | OS | Status |
|
||||||
| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| inotify | Linux 2.6.27 or later, Android\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
|
| inotify | Linux 2.6.27 or later, Android\* | Supported |
|
||||||
| kqueue | BSD, macOS, iOS\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
|
| kqueue | BSD, macOS, iOS\* | Supported |
|
||||||
| ReadDirectoryChangesW | Windows | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
|
| ReadDirectoryChangesW | Windows | Supported |
|
||||||
| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) |
|
| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) |
|
||||||
| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) |
|
| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) |
|
||||||
| fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) |
|
| fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) |
|
||||||
|
1
vendor/github.com/fsnotify/fsnotify/fen.go
generated
vendored
1
vendor/github.com/fsnotify/fsnotify/fen.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build solaris
|
||||||
// +build solaris
|
// +build solaris
|
||||||
|
|
||||||
package fsnotify
|
package fsnotify
|
||||||
|
1
vendor/github.com/fsnotify/fsnotify/fsnotify.go
generated
vendored
1
vendor/github.com/fsnotify/fsnotify/fsnotify.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !plan9
|
||||||
// +build !plan9
|
// +build !plan9
|
||||||
|
|
||||||
// Package fsnotify provides a platform-independent interface for file system notifications.
|
// Package fsnotify provides a platform-independent interface for file system notifications.
|
||||||
|
5
vendor/github.com/fsnotify/fsnotify/go.mod
generated
vendored
5
vendor/github.com/fsnotify/fsnotify/go.mod
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
module github.com/fsnotify/fsnotify
|
|
||||||
|
|
||||||
go 1.13
|
|
||||||
|
|
||||||
require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9
|
|
2
vendor/github.com/fsnotify/fsnotify/go.sum
generated
vendored
2
vendor/github.com/fsnotify/fsnotify/go.sum
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
|
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
3
vendor/github.com/fsnotify/fsnotify/inotify.go
generated
vendored
3
vendor/github.com/fsnotify/fsnotify/inotify.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build linux
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package fsnotify
|
package fsnotify
|
||||||
@ -272,7 +273,7 @@ func (w *Watcher) readEvents() {
|
|||||||
|
|
||||||
if nameLen > 0 {
|
if nameLen > 0 {
|
||||||
// Point "bytes" at the first byte of the filename
|
// Point "bytes" at the first byte of the filename
|
||||||
bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))
|
bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))[:nameLen:nameLen]
|
||||||
// The filename is padded with NULL bytes. TrimRight() gets rid of those.
|
// The filename is padded with NULL bytes. TrimRight() gets rid of those.
|
||||||
name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
|
name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/fsnotify/fsnotify/inotify_poller.go
generated
vendored
1
vendor/github.com/fsnotify/fsnotify/inotify_poller.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build linux
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package fsnotify
|
package fsnotify
|
||||||
|
1
vendor/github.com/fsnotify/fsnotify/kqueue.go
generated
vendored
1
vendor/github.com/fsnotify/fsnotify/kqueue.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build freebsd || openbsd || netbsd || dragonfly || darwin
|
||||||
// +build freebsd openbsd netbsd dragonfly darwin
|
// +build freebsd openbsd netbsd dragonfly darwin
|
||||||
|
|
||||||
package fsnotify
|
package fsnotify
|
||||||
|
1
vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
generated
vendored
1
vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build freebsd || openbsd || netbsd || dragonfly
|
||||||
// +build freebsd openbsd netbsd dragonfly
|
// +build freebsd openbsd netbsd dragonfly
|
||||||
|
|
||||||
package fsnotify
|
package fsnotify
|
||||||
|
1
vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
generated
vendored
1
vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build darwin
|
||||||
// +build darwin
|
// +build darwin
|
||||||
|
|
||||||
package fsnotify
|
package fsnotify
|
||||||
|
1
vendor/github.com/fsnotify/fsnotify/windows.go
generated
vendored
1
vendor/github.com/fsnotify/fsnotify/windows.go
generated
vendored
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package fsnotify
|
package fsnotify
|
||||||
|
3
vendor/github.com/ghodss/yaml/go.mod
generated
vendored
3
vendor/github.com/ghodss/yaml/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
module github.com/ghodss/yaml
|
|
||||||
|
|
||||||
require gopkg.in/yaml.v2 v2.2.2
|
|
3
vendor/github.com/ghodss/yaml/go.sum
generated
vendored
3
vendor/github.com/ghodss/yaml/go.sum
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
29
vendor/github.com/go-logr/logr/.golangci.yaml
generated
vendored
Normal file
29
vendor/github.com/go-logr/logr/.golangci.yaml
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
run:
|
||||||
|
timeout: 1m
|
||||||
|
tests: true
|
||||||
|
|
||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- asciicheck
|
||||||
|
- deadcode
|
||||||
|
- errcheck
|
||||||
|
- forcetypeassert
|
||||||
|
- gocritic
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- misspell
|
||||||
|
- revive
|
||||||
|
- staticcheck
|
||||||
|
- structcheck
|
||||||
|
- typecheck
|
||||||
|
- unused
|
||||||
|
- varcheck
|
||||||
|
|
||||||
|
issues:
|
||||||
|
exclude-use-default: false
|
||||||
|
max-issues-per-linter: 0
|
||||||
|
max-same-issues: 10
|
6
vendor/github.com/go-logr/logr/CHANGELOG.md
generated
vendored
Normal file
6
vendor/github.com/go-logr/logr/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v1.0.0-rc1
|
||||||
|
|
||||||
|
This is the first logged release. Major changes (including breaking changes)
|
||||||
|
have occurred since earlier tags.
|
17
vendor/github.com/go-logr/logr/CONTRIBUTING.md
generated
vendored
Normal file
17
vendor/github.com/go-logr/logr/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
Logr is open to pull-requests, provided they fit within the intended scope of
|
||||||
|
the project. Specifically, this library aims to be VERY small and minimalist,
|
||||||
|
with no external dependencies.
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
This project intends to follow [semantic versioning](http://semver.org) and
|
||||||
|
is very strict about compatibility. Any proposed changes MUST follow those
|
||||||
|
rules.
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
As a logging library, logr must be as light-weight as possible. Any proposed
|
||||||
|
code change must include results of running the [benchmark](./benchmark)
|
||||||
|
before and after the change.
|
209
vendor/github.com/go-logr/logr/README.md
generated
vendored
209
vendor/github.com/go-logr/logr/README.md
generated
vendored
@ -1,112 +1,182 @@
|
|||||||
# A more minimal logging API for Go
|
# A minimal logging API for Go
|
||||||
|
|
||||||
|
[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr)
|
||||||
|
|
||||||
|
logr offers an(other) opinion on how Go programs and libraries can do logging
|
||||||
|
without becoming coupled to a particular logging implementation. This is not
|
||||||
|
an implementation of logging - it is an API. In fact it is two APIs with two
|
||||||
|
different sets of users.
|
||||||
|
|
||||||
|
The `Logger` type is intended for application and library authors. It provides
|
||||||
|
a relatively small API which can be used everywhere you want to emit logs. It
|
||||||
|
defers the actual act of writing logs (to files, to stdout, or whatever) to the
|
||||||
|
`LogSink` interface.
|
||||||
|
|
||||||
|
The `LogSink` interface is intended for logging library implementers. It is a
|
||||||
|
pure interface which can be implemented by logging frameworks to provide the actual logging
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
This decoupling allows application and library developers to write code in
|
||||||
|
terms of `logr.Logger` (which has very low dependency fan-out) while the
|
||||||
|
implementation of logging is managed "up stack" (e.g. in or near `main()`.)
|
||||||
|
Application developers can then switch out implementations as necessary.
|
||||||
|
|
||||||
|
Many people assert that libraries should not be logging, and as such efforts
|
||||||
|
like this are pointless. Those people are welcome to convince the authors of
|
||||||
|
the tens-of-thousands of libraries that *DO* write logs that they are all
|
||||||
|
wrong. In the meantime, logr takes a more practical approach.
|
||||||
|
|
||||||
|
## Typical usage
|
||||||
|
|
||||||
|
Somewhere, early in an application's life, it will make a decision about which
|
||||||
|
logging library (implementation) it actually wants to use. Something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
func main() {
|
||||||
|
// ... other setup code ...
|
||||||
|
|
||||||
|
// Create the "root" logger. We have chosen the "logimpl" implementation,
|
||||||
|
// which takes some initial parameters and returns a logr.Logger.
|
||||||
|
logger := logimpl.New(param1, param2)
|
||||||
|
|
||||||
|
// ... other setup code ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Most apps will call into other libraries, create structures to govern the flow,
|
||||||
|
etc. The `logr.Logger` object can be passed to these other libraries, stored
|
||||||
|
in structs, or even used as a package-global variable, if needed. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
app := createTheAppObject(logger)
|
||||||
|
app.Run()
|
||||||
|
```
|
||||||
|
|
||||||
|
Outside of this early setup, no other packages need to know about the choice of
|
||||||
|
implementation. They write logs in terms of the `logr.Logger` that they
|
||||||
|
received:
|
||||||
|
|
||||||
|
```
|
||||||
|
type appObject struct {
|
||||||
|
// ... other fields ...
|
||||||
|
logger logr.Logger
|
||||||
|
// ... other fields ...
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *appObject) Run() {
|
||||||
|
app.logger.Info("starting up", "timestamp", time.Now())
|
||||||
|
|
||||||
|
// ... app code ...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
If the Go standard library had defined an interface for logging, this project
|
||||||
|
probably would not be needed. Alas, here we are.
|
||||||
|
|
||||||
|
### Inspiration
|
||||||
|
|
||||||
Before you consider this package, please read [this blog post by the
|
Before you consider this package, please read [this blog post by the
|
||||||
inimitable Dave Cheney][warning-makes-no-sense]. I really appreciate what
|
inimitable Dave Cheney][warning-makes-no-sense]. We really appreciate what
|
||||||
he has to say, and it largely aligns with my own experiences. Too many
|
he has to say, and it largely aligns with our own experiences.
|
||||||
choices of levels means inconsistent logs.
|
|
||||||
|
|
||||||
This package offers a purely abstract interface, based on these ideas but with
|
### Differences from Dave's ideas
|
||||||
a few twists. Code can depend on just this interface and have the actual
|
|
||||||
logging implementation be injected from callers. Ideally only `main()` knows
|
|
||||||
what logging implementation is being used.
|
|
||||||
|
|
||||||
# Differences from Dave's ideas
|
|
||||||
|
|
||||||
The main differences are:
|
The main differences are:
|
||||||
|
|
||||||
1) Dave basically proposes doing away with the notion of a logging API in favor
|
1. Dave basically proposes doing away with the notion of a logging API in favor
|
||||||
of `fmt.Printf()`. I disagree, especially when you consider things like output
|
of `fmt.Printf()`. We disagree, especially when you consider things like output
|
||||||
locations, timestamps, file and line decorations, and structured logging. I
|
locations, timestamps, file and line decorations, and structured logging. This
|
||||||
restrict the API to just 2 types of logs: info and error.
|
package restricts the logging API to just 2 types of logs: info and error.
|
||||||
|
|
||||||
Info logs are things you want to tell the user which are not errors. Error
|
Info logs are things you want to tell the user which are not errors. Error
|
||||||
logs are, well, errors. If your code receives an `error` from a subordinate
|
logs are, well, errors. If your code receives an `error` from a subordinate
|
||||||
function call and is logging that `error` *and not returning it*, use error
|
function call and is logging that `error` *and not returning it*, use error
|
||||||
logs.
|
logs.
|
||||||
|
|
||||||
2) Verbosity-levels on info logs. This gives developers a chance to indicate
|
2. Verbosity-levels on info logs. This gives developers a chance to indicate
|
||||||
arbitrary grades of importance for info logs, without assigning names with
|
arbitrary grades of importance for info logs, without assigning names with
|
||||||
semantic meaning such as "warning", "trace", and "debug". Superficially this
|
semantic meaning such as "warning", "trace", and "debug." Superficially this
|
||||||
may feel very similar, but the primary difference is the lack of semantics.
|
may feel very similar, but the primary difference is the lack of semantics.
|
||||||
Because verbosity is a numerical value, it's safe to assume that an app running
|
Because verbosity is a numerical value, it's safe to assume that an app running
|
||||||
with higher verbosity means more (and less important) logs will be generated.
|
with higher verbosity means more (and less important) logs will be generated.
|
||||||
|
|
||||||
This is a BETA grade API.
|
## Implementations (non-exhaustive)
|
||||||
|
|
||||||
There are implementations for the following logging libraries:
|
There are implementations for the following logging libraries:
|
||||||
|
|
||||||
|
- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr)
|
||||||
- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)
|
- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)
|
||||||
- **k8s.io/klog**: [klogr](https://git.k8s.io/klog/klogr)
|
- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr)
|
||||||
- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)
|
- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)
|
||||||
- **log** (the Go standard library logger):
|
- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr)
|
||||||
[stdr](https://github.com/go-logr/stdr)
|
|
||||||
- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)
|
- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)
|
||||||
- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)
|
- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)
|
||||||
- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)
|
- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)
|
||||||
|
- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr)
|
||||||
|
|
||||||
# FAQ
|
## FAQ
|
||||||
|
|
||||||
## Conceptual
|
### Conceptual
|
||||||
|
|
||||||
## Why structured logging?
|
#### Why structured logging?
|
||||||
|
|
||||||
- **Structured logs are more easily queriable**: Since you've got
|
- **Structured logs are more easily queryable**: Since you've got
|
||||||
key-value pairs, it's much easier to query your structured logs for
|
key-value pairs, it's much easier to query your structured logs for
|
||||||
particular values by filtering on the contents of a particular key --
|
particular values by filtering on the contents of a particular key --
|
||||||
think searching request logs for error codes, Kubernetes reconcilers for
|
think searching request logs for error codes, Kubernetes reconcilers for
|
||||||
the name and namespace of the reconciled object, etc
|
the name and namespace of the reconciled object, etc.
|
||||||
|
|
||||||
- **Structured logging makes it easier to have cross-referencable logs**:
|
- **Structured logging makes it easier to have cross-referenceable logs**:
|
||||||
Similarly to searchability, if you maintain conventions around your
|
Similarly to searchability, if you maintain conventions around your
|
||||||
keys, it becomes easy to gather all log lines related to a particular
|
keys, it becomes easy to gather all log lines related to a particular
|
||||||
concept.
|
concept.
|
||||||
|
|
||||||
- **Structured logs allow better dimensions of filtering**: if you have
|
- **Structured logs allow better dimensions of filtering**: if you have
|
||||||
structure to your logs, you've got more precise control over how much
|
structure to your logs, you've got more precise control over how much
|
||||||
information is logged -- you might choose in a particular configuration
|
information is logged -- you might choose in a particular configuration
|
||||||
to log certain keys but not others, only log lines where a certain key
|
to log certain keys but not others, only log lines where a certain key
|
||||||
matches a certain value, etc, instead of just having v-levels and names
|
matches a certain value, etc., instead of just having v-levels and names
|
||||||
to key off of.
|
to key off of.
|
||||||
|
|
||||||
- **Structured logs better represent structured data**: sometimes, the
|
- **Structured logs better represent structured data**: sometimes, the
|
||||||
data that you want to log is inherently structured (think tuple-link
|
data that you want to log is inherently structured (think tuple-link
|
||||||
objects). Structured logs allow you to preserve that structure when
|
objects.) Structured logs allow you to preserve that structure when
|
||||||
outputting.
|
outputting.
|
||||||
|
|
||||||
## Why V-levels?
|
#### Why V-levels?
|
||||||
|
|
||||||
**V-levels give operators an easy way to control the chattiness of log
|
**V-levels give operators an easy way to control the chattiness of log
|
||||||
operations**. V-levels provide a way for a given package to distinguish
|
operations**. V-levels provide a way for a given package to distinguish
|
||||||
the relative importance or verbosity of a given log message. Then, if
|
the relative importance or verbosity of a given log message. Then, if
|
||||||
a particular logger or package is logging too many messages, the user
|
a particular logger or package is logging too many messages, the user
|
||||||
of the package can simply change the v-levels for that library.
|
of the package can simply change the v-levels for that library.
|
||||||
|
|
||||||
## Why not more named levels, like Warning?
|
#### Why not named levels, like Info/Warning/Error?
|
||||||
|
|
||||||
Read [Dave Cheney's post][warning-makes-no-sense]. Then read [Differences
|
Read [Dave Cheney's post][warning-makes-no-sense]. Then read [Differences
|
||||||
from Dave's ideas](#differences-from-daves-ideas).
|
from Dave's ideas](#differences-from-daves-ideas).
|
||||||
|
|
||||||
## Why not allow format strings, too?
|
#### Why not allow format strings, too?
|
||||||
|
|
||||||
**Format strings negate many of the benefits of structured logs**:
|
**Format strings negate many of the benefits of structured logs**:
|
||||||
|
|
||||||
- They're not easily searchable without resorting to fuzzy searching,
|
- They're not easily searchable without resorting to fuzzy searching,
|
||||||
regular expressions, etc
|
regular expressions, etc.
|
||||||
|
|
||||||
- They don't store structured data well, since contents are flattened into
|
- They don't store structured data well, since contents are flattened into
|
||||||
a string
|
a string.
|
||||||
|
|
||||||
- They're not cross-referencable
|
- They're not cross-referenceable.
|
||||||
|
|
||||||
- They don't compress easily, since the message is not constant
|
- They don't compress easily, since the message is not constant.
|
||||||
|
|
||||||
(unless you turn positional parameters into key-value pairs with numerical
|
(Unless you turn positional parameters into key-value pairs with numerical
|
||||||
keys, at which point you've gotten key-value logging with meaningless
|
keys, at which point you've gotten key-value logging with meaningless
|
||||||
keys)
|
keys.)
|
||||||
|
|
||||||
## Practical
|
### Practical
|
||||||
|
|
||||||
## Why key-value pairs, and not a map?
|
#### Why key-value pairs, and not a map?
|
||||||
|
|
||||||
Key-value pairs are *much* easier to optimize, especially around
|
Key-value pairs are *much* easier to optimize, especially around
|
||||||
allocations. Zap (a structured logger that inspired logr's interface) has
|
allocations. Zap (a structured logger that inspired logr's interface) has
|
||||||
@ -117,26 +187,26 @@ While the interface ends up being a little less obvious, you get
|
|||||||
potentially better performance, plus avoid making users type
|
potentially better performance, plus avoid making users type
|
||||||
`map[string]string{}` every time they want to log.
|
`map[string]string{}` every time they want to log.
|
||||||
|
|
||||||
## What if my V-levels differ between libraries?
|
#### What if my V-levels differ between libraries?
|
||||||
|
|
||||||
That's fine. Control your V-levels on a per-logger basis, and use the
|
That's fine. Control your V-levels on a per-logger basis, and use the
|
||||||
`WithName` function to pass different loggers to different libraries.
|
`WithName` method to pass different loggers to different libraries.
|
||||||
|
|
||||||
Generally, you should take care to ensure that you have relatively
|
Generally, you should take care to ensure that you have relatively
|
||||||
consistent V-levels within a given logger, however, as this makes deciding
|
consistent V-levels within a given logger, however, as this makes deciding
|
||||||
on what verbosity of logs to request easier.
|
on what verbosity of logs to request easier.
|
||||||
|
|
||||||
## But I *really* want to use a format string!
|
#### But I really want to use a format string!
|
||||||
|
|
||||||
That's not actually a question. Assuming your question is "how do
|
That's not actually a question. Assuming your question is "how do
|
||||||
I convert my mental model of logging with format strings to logging with
|
I convert my mental model of logging with format strings to logging with
|
||||||
constant messages":
|
constant messages":
|
||||||
|
|
||||||
1. figure out what the error actually is, as you'd write in a TL;DR style,
|
1. Figure out what the error actually is, as you'd write in a TL;DR style,
|
||||||
and use that as a message
|
and use that as a message.
|
||||||
|
|
||||||
2. For every place you'd write a format specifier, look to the word before
|
2. For every place you'd write a format specifier, look to the word before
|
||||||
it, and add that as a key value pair
|
it, and add that as a key value pair.
|
||||||
|
|
||||||
For instance, consider the following examples (all taken from spots in the
|
For instance, consider the following examples (all taken from spots in the
|
||||||
Kubernetes codebase):
|
Kubernetes codebase):
|
||||||
@ -150,34 +220,59 @@ Kubernetes codebase):
|
|||||||
response when requesting url", "attempt", retries, "after
|
response when requesting url", "attempt", retries, "after
|
||||||
seconds", seconds, "url", url)`
|
seconds", seconds, "url", url)`
|
||||||
|
|
||||||
If you *really* must use a format string, place it as a key value, and
|
If you *really* must use a format string, use it in a key's value, and
|
||||||
call `fmt.Sprintf` yourself -- for instance, `log.Printf("unable to
|
call `fmt.Sprintf` yourself. For instance: `log.Printf("unable to
|
||||||
reflect over type %T")` becomes `logger.Info("unable to reflect over
|
reflect over type %T")` becomes `logger.Info("unable to reflect over
|
||||||
type", "type", fmt.Sprintf("%T"))`. In general though, the cases where
|
type", "type", fmt.Sprintf("%T"))`. In general though, the cases where
|
||||||
this is necessary should be few and far between.
|
this is necessary should be few and far between.
|
||||||
|
|
||||||
## How do I choose my V-levels?
|
#### How do I choose my V-levels?
|
||||||
|
|
||||||
This is basically the only hard constraint: increase V-levels to denote
|
This is basically the only hard constraint: increase V-levels to denote
|
||||||
more verbose or more debug-y logs.
|
more verbose or more debug-y logs.
|
||||||
|
|
||||||
Otherwise, you can start out with `0` as "you always want to see this",
|
Otherwise, you can start out with `0` as "you always want to see this",
|
||||||
`1` as "common logging that you might *possibly* want to turn off", and
|
`1` as "common logging that you might *possibly* want to turn off", and
|
||||||
`10` as "I would like to performance-test your log collection stack".
|
`10` as "I would like to performance-test your log collection stack."
|
||||||
|
|
||||||
Then gradually choose levels in between as you need them, working your way
|
Then gradually choose levels in between as you need them, working your way
|
||||||
down from 10 (for debug and trace style logs) and up from 1 (for chattier
|
down from 10 (for debug and trace style logs) and up from 1 (for chattier
|
||||||
info-type logs).
|
info-type logs.)
|
||||||
|
|
||||||
## How do I choose my keys
|
#### How do I choose my keys?
|
||||||
|
|
||||||
- make your keys human-readable
|
Keys are fairly flexible, and can hold more or less any string
|
||||||
- constant keys are generally a good idea
|
value. For best compatibility with implementations and consistency
|
||||||
- be consistent across your codebase
|
with existing code in other projects, there are a few conventions you
|
||||||
- keys should naturally match parts of the message string
|
should consider.
|
||||||
|
|
||||||
|
- Make your keys human-readable.
|
||||||
|
- Constant keys are generally a good idea.
|
||||||
|
- Be consistent across your codebase.
|
||||||
|
- Keys should naturally match parts of the message string.
|
||||||
|
- Use lower case for simple keys and
|
||||||
|
[lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for
|
||||||
|
more complex ones. Kubernetes is one example of a project that has
|
||||||
|
[adopted that
|
||||||
|
convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments).
|
||||||
|
|
||||||
While key names are mostly unrestricted (and spaces are acceptable),
|
While key names are mostly unrestricted (and spaces are acceptable),
|
||||||
it's generally a good idea to stick to printable ascii characters, or at
|
it's generally a good idea to stick to printable ascii characters, or at
|
||||||
least match the general character set of your log lines.
|
least match the general character set of your log lines.
|
||||||
|
|
||||||
|
#### Why should keys be constant values?
|
||||||
|
|
||||||
|
The point of structured logging is to make later log processing easier. Your
|
||||||
|
keys are, effectively, the schema of each log message. If you use different
|
||||||
|
keys across instances of the same log line, you will make your structured logs
|
||||||
|
much harder to use. `Sprintf()` is for values, not for keys!
|
||||||
|
|
||||||
|
#### Why is this not a pure interface?
|
||||||
|
|
||||||
|
The Logger type is implemented as a struct in order to allow the Go compiler to
|
||||||
|
optimize things like high-V `Info` logs that are not triggered. Not all of
|
||||||
|
these implementations are implemented yet, but this structure was suggested as
|
||||||
|
a way to ensure they *can* be implemented. All of the real work is behind the
|
||||||
|
`LogSink` interface.
|
||||||
|
|
||||||
[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
||||||
|
37
vendor/github.com/go-logr/logr/discard.go
generated
vendored
37
vendor/github.com/go-logr/logr/discard.go
generated
vendored
@ -16,36 +16,39 @@ limitations under the License.
|
|||||||
|
|
||||||
package logr
|
package logr
|
||||||
|
|
||||||
// Discard returns a valid Logger that discards all messages logged to it.
|
// Discard returns a Logger that discards all messages logged to it. It can be
|
||||||
// It can be used whenever the caller is not interested in the logs.
|
// used whenever the caller is not interested in the logs. Logger instances
|
||||||
|
// produced by this function always compare as equal.
|
||||||
func Discard() Logger {
|
func Discard() Logger {
|
||||||
return DiscardLogger{}
|
return Logger{
|
||||||
|
level: 0,
|
||||||
|
sink: discardLogSink{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DiscardLogger is a Logger that discards all messages.
|
// discardLogSink is a LogSink that discards all messages.
|
||||||
type DiscardLogger struct{}
|
type discardLogSink struct{}
|
||||||
|
|
||||||
func (l DiscardLogger) Enabled() bool {
|
// Verify that it actually implements the interface
|
||||||
|
var _ LogSink = discardLogSink{}
|
||||||
|
|
||||||
|
func (l discardLogSink) Init(RuntimeInfo) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l discardLogSink) Enabled(int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l DiscardLogger) Info(msg string, keysAndValues ...interface{}) {
|
func (l discardLogSink) Info(int, string, ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l DiscardLogger) Error(err error, msg string, keysAndValues ...interface{}) {
|
func (l discardLogSink) Error(error, string, ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l DiscardLogger) V(level int) Logger {
|
func (l discardLogSink) WithValues(...interface{}) LogSink {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l DiscardLogger) WithValues(keysAndValues ...interface{}) Logger {
|
func (l discardLogSink) WithName(string) LogSink {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l DiscardLogger) WithName(name string) Logger {
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that it actually implements the interface
|
|
||||||
var _ Logger = DiscardLogger{}
|
|
||||||
|
3
vendor/github.com/go-logr/logr/go.mod
generated
vendored
3
vendor/github.com/go-logr/logr/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
module github.com/go-logr/logr
|
|
||||||
|
|
||||||
go 1.14
|
|
544
vendor/github.com/go-logr/logr/logr.go
generated
vendored
544
vendor/github.com/go-logr/logr/logr.go
generated
vendored
@ -16,83 +16,101 @@ limitations under the License.
|
|||||||
|
|
||||||
// This design derives from Dave Cheney's blog:
|
// This design derives from Dave Cheney's blog:
|
||||||
// http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
// http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
||||||
//
|
|
||||||
// This is a BETA grade API. Until there is a significant 2nd implementation,
|
|
||||||
// I don't really know how it will change.
|
|
||||||
|
|
||||||
// Package logr defines abstract interfaces for logging. Packages can depend on
|
// Package logr defines a general-purpose logging API and abstract interfaces
|
||||||
// these interfaces and callers can implement logging in whatever way is
|
// to back that API. Packages in the Go ecosystem can depend on this package,
|
||||||
// appropriate.
|
// while callers can implement logging with whatever backend is appropriate.
|
||||||
//
|
//
|
||||||
// Usage
|
// Usage
|
||||||
//
|
//
|
||||||
// Logging is done using a Logger. Loggers can have name prefixes and named
|
// Logging is done using a Logger instance. Logger is a concrete type with
|
||||||
// values attached, so that all log messages logged with that Logger have some
|
// methods, which defers the actual logging to a LogSink interface. The main
|
||||||
// base context associated.
|
// methods of Logger are Info() and Error(). Arguments to Info() and Error()
|
||||||
|
// are key/value pairs rather than printf-style formatted strings, emphasizing
|
||||||
|
// "structured logging".
|
||||||
//
|
//
|
||||||
// The term "key" is used to refer to the name associated with a particular
|
// With Go's standard log package, we might write:
|
||||||
// value, to disambiguate it from the general Logger name.
|
// log.Printf("setting target value %s", targetValue)
|
||||||
//
|
//
|
||||||
// For instance, suppose we're trying to reconcile the state of an object, and
|
// With logr's structured logging, we'd write:
|
||||||
// we want to log that we've made some decision.
|
// logger.Info("setting target", "value", targetValue)
|
||||||
//
|
//
|
||||||
// With the traditional log package, we might write:
|
// Errors are much the same. Instead of:
|
||||||
|
// log.Printf("failed to open the pod bay door for user %s: %v", user, err)
|
||||||
|
//
|
||||||
|
// We'd write:
|
||||||
|
// logger.Error(err, "failed to open the pod bay door", "user", user)
|
||||||
|
//
|
||||||
|
// Info() and Error() are very similar, but they are separate methods so that
|
||||||
|
// LogSink implementations can choose to do things like attach additional
|
||||||
|
// information (such as stack traces) on calls to Error().
|
||||||
|
//
|
||||||
|
// Verbosity
|
||||||
|
//
|
||||||
|
// Often we want to log information only when the application in "verbose
|
||||||
|
// mode". To write log lines that are more verbose, Logger has a V() method.
|
||||||
|
// The higher the V-level of a log line, the less critical it is considered.
|
||||||
|
// Log-lines with V-levels that are not enabled (as per the LogSink) will not
|
||||||
|
// be written. Level V(0) is the default, and logger.V(0).Info() has the same
|
||||||
|
// meaning as logger.Info(). Negative V-levels have the same meaning as V(0).
|
||||||
|
//
|
||||||
|
// Where we might have written:
|
||||||
|
// if flVerbose >= 2 {
|
||||||
|
// log.Printf("an unusual thing happened")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// We can write:
|
||||||
|
// logger.V(2).Info("an unusual thing happened")
|
||||||
|
//
|
||||||
|
// Logger Names
|
||||||
|
//
|
||||||
|
// Logger instances can have name strings so that all messages logged through
|
||||||
|
// that instance have additional context. For example, you might want to add
|
||||||
|
// a subsystem name:
|
||||||
|
//
|
||||||
|
// logger.WithName("compactor").Info("started", "time", time.Now())
|
||||||
|
//
|
||||||
|
// The WithName() method returns a new Logger, which can be passed to
|
||||||
|
// constructors or other functions for further use. Repeated use of WithName()
|
||||||
|
// will accumulate name "segments". These name segments will be joined in some
|
||||||
|
// way by the LogSink implementation. It is strongly recommended that name
|
||||||
|
// segments contain simple identifiers (letters, digits, and hyphen), and do
|
||||||
|
// not contain characters that could muddle the log output or confuse the
|
||||||
|
// joining operation (e.g. whitespace, commas, periods, slashes, brackets,
|
||||||
|
// quotes, etc).
|
||||||
|
//
|
||||||
|
// Saved Values
|
||||||
|
//
|
||||||
|
// Logger instances can store any number of key/value pairs, which will be
|
||||||
|
// logged alongside all messages logged through that instance. For example,
|
||||||
|
// you might want to create a Logger instance per managed object:
|
||||||
|
//
|
||||||
|
// With the standard log package, we might write:
|
||||||
// log.Printf("decided to set field foo to value %q for object %s/%s",
|
// log.Printf("decided to set field foo to value %q for object %s/%s",
|
||||||
// targetValue, object.Namespace, object.Name)
|
// targetValue, object.Namespace, object.Name)
|
||||||
//
|
//
|
||||||
// With logr's structured logging, we'd write:
|
// With logr we'd write:
|
||||||
// // elsewhere in the file, set up the logger to log with the prefix of
|
// // Elsewhere: set up the logger to log the object name.
|
||||||
// // "reconcilers", and the named value target-type=Foo, for extra context.
|
// obj.logger = mainLogger.WithValues(
|
||||||
// log := mainLogger.WithName("reconcilers").WithValues("target-type", "Foo")
|
// "name", obj.name, "namespace", obj.namespace)
|
||||||
//
|
//
|
||||||
// // later on...
|
// // later on...
|
||||||
// log.Info("setting foo on object", "value", targetValue, "object", object)
|
// obj.logger.Info("setting foo", "value", targetValue)
|
||||||
//
|
//
|
||||||
// Depending on our logging implementation, we could then make logging decisions
|
// Best Practices
|
||||||
// based on field values (like only logging such events for objects in a certain
|
|
||||||
// namespace), or copy the structured information into a structured log store.
|
|
||||||
//
|
//
|
||||||
// For logging errors, Logger has a method called Error. Suppose we wanted to
|
// Logger has very few hard rules, with the goal that LogSink implementations
|
||||||
// log an error while reconciling. With the traditional log package, we might
|
// might have a lot of freedom to differentiate. There are, however, some
|
||||||
// write:
|
// things to consider.
|
||||||
// log.Errorf("unable to reconcile object %s/%s: %v", object.Namespace, object.Name, err)
|
|
||||||
//
|
|
||||||
// With logr, we'd instead write:
|
|
||||||
// // assuming the above setup for log
|
|
||||||
// log.Error(err, "unable to reconcile object", "object", object)
|
|
||||||
//
|
|
||||||
// This functions similarly to:
|
|
||||||
// log.Info("unable to reconcile object", "error", err, "object", object)
|
|
||||||
//
|
|
||||||
// However, it ensures that a standard key for the error value ("error") is used
|
|
||||||
// across all error logging. Furthermore, certain implementations may choose to
|
|
||||||
// attach additional information (such as stack traces) on calls to Error, so
|
|
||||||
// it's preferred to use Error to log errors.
|
|
||||||
//
|
|
||||||
// Parts of a log line
|
|
||||||
//
|
|
||||||
// Each log message from a Logger has four types of context:
|
|
||||||
// logger name, log verbosity, log message, and the named values.
|
|
||||||
//
|
|
||||||
// The Logger name consists of a series of name "segments" added by successive
|
|
||||||
// calls to WithName. These name segments will be joined in some way by the
|
|
||||||
// underlying implementation. It is strongly recommended that name segments
|
|
||||||
// contain simple identifiers (letters, digits, and hyphen), and do not contain
|
|
||||||
// characters that could muddle the log output or confuse the joining operation
|
|
||||||
// (e.g. whitespace, commas, periods, slashes, brackets, quotes, etc).
|
|
||||||
//
|
|
||||||
// Log verbosity represents how little a log matters. Level zero, the default,
|
|
||||||
// matters most. Increasing levels matter less and less. Try to avoid lots of
|
|
||||||
// different verbosity levels, and instead provide useful keys, logger names,
|
|
||||||
// and log messages for users to filter on. It's illegal to pass a log level
|
|
||||||
// below zero.
|
|
||||||
//
|
//
|
||||||
// The log message consists of a constant message attached to the log line.
|
// The log message consists of a constant message attached to the log line.
|
||||||
// This should generally be a simple description of what's occurring, and should
|
// This should generally be a simple description of what's occurring, and should
|
||||||
// never be a format string.
|
// never be a format string. Variable information can then be attached using
|
||||||
|
// named values.
|
||||||
//
|
//
|
||||||
// Variable information can then be attached using named values (key/value
|
// Keys are arbitrary strings, but should generally be constant values. Values
|
||||||
// pairs). Keys are arbitrary strings, while values may be any Go value.
|
// may be any Go value, but how the value is formatted is determined by the
|
||||||
|
// LogSink implementation.
|
||||||
//
|
//
|
||||||
// Key Naming Conventions
|
// Key Naming Conventions
|
||||||
//
|
//
|
||||||
@ -102,6 +120,7 @@ limitations under the License.
|
|||||||
// * be constant (not dependent on input data)
|
// * be constant (not dependent on input data)
|
||||||
// * contain only printable characters
|
// * contain only printable characters
|
||||||
// * not contain whitespace or punctuation
|
// * not contain whitespace or punctuation
|
||||||
|
// * use lower case for simple keys and lowerCamelCase for more complex ones
|
||||||
//
|
//
|
||||||
// These guidelines help ensure that log data is processed properly regardless
|
// These guidelines help ensure that log data is processed properly regardless
|
||||||
// of the log implementation. For example, log implementations will try to
|
// of the log implementation. For example, log implementations will try to
|
||||||
@ -110,21 +129,22 @@ limitations under the License.
|
|||||||
// While users are generally free to use key names of their choice, it's
|
// While users are generally free to use key names of their choice, it's
|
||||||
// generally best to avoid using the following keys, as they're frequently used
|
// generally best to avoid using the following keys, as they're frequently used
|
||||||
// by implementations:
|
// by implementations:
|
||||||
//
|
// * "caller": the calling information (file/line) of a particular log line
|
||||||
// * `"caller"`: the calling information (file/line) of a particular log line.
|
// * "error": the underlying error value in the `Error` method
|
||||||
// * `"error"`: the underlying error value in the `Error` method.
|
// * "level": the log level
|
||||||
// * `"level"`: the log level.
|
// * "logger": the name of the associated logger
|
||||||
// * `"logger"`: the name of the associated logger.
|
// * "msg": the log message
|
||||||
// * `"msg"`: the log message.
|
// * "stacktrace": the stack trace associated with a particular log line or
|
||||||
// * `"stacktrace"`: the stack trace associated with a particular log line or
|
// error (often from the `Error` message)
|
||||||
// error (often from the `Error` message).
|
// * "ts": the timestamp for a log line
|
||||||
// * `"ts"`: the timestamp for a log line.
|
|
||||||
//
|
//
|
||||||
// Implementations are encouraged to make use of these keys to represent the
|
// Implementations are encouraged to make use of these keys to represent the
|
||||||
// above concepts, when necessary (for example, in a pure-JSON output form, it
|
// above concepts, when necessary (for example, in a pure-JSON output form, it
|
||||||
// would be necessary to represent at least message and timestamp as ordinary
|
// would be necessary to represent at least message and timestamp as ordinary
|
||||||
// named values).
|
// named values).
|
||||||
//
|
//
|
||||||
|
// Break Glass
|
||||||
|
//
|
||||||
// Implementations may choose to give callers access to the underlying
|
// Implementations may choose to give callers access to the underlying
|
||||||
// logging implementation. The recommended pattern for this is:
|
// logging implementation. The recommended pattern for this is:
|
||||||
// // Underlier exposes access to the underlying logging implementation.
|
// // Underlier exposes access to the underlying logging implementation.
|
||||||
@ -134,81 +154,220 @@ limitations under the License.
|
|||||||
// type Underlier interface {
|
// type Underlier interface {
|
||||||
// GetUnderlying() <underlying-type>
|
// GetUnderlying() <underlying-type>
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
|
// Logger grants access to the sink to enable type assertions like this:
|
||||||
|
// func DoSomethingWithImpl(log logr.Logger) {
|
||||||
|
// if underlier, ok := log.GetSink()(impl.Underlier) {
|
||||||
|
// implLogger := underlier.GetUnderlying()
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Custom `With*` functions can be implemented by copying the complete
|
||||||
|
// Logger struct and replacing the sink in the copy:
|
||||||
|
// // WithFooBar changes the foobar parameter in the log sink and returns a
|
||||||
|
// // new logger with that modified sink. It does nothing for loggers where
|
||||||
|
// // the sink doesn't support that parameter.
|
||||||
|
// func WithFoobar(log logr.Logger, foobar int) logr.Logger {
|
||||||
|
// if foobarLogSink, ok := log.GetSink()(FoobarSink); ok {
|
||||||
|
// log = log.WithSink(foobarLogSink.WithFooBar(foobar))
|
||||||
|
// }
|
||||||
|
// return log
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Don't use New to construct a new Logger with a LogSink retrieved from an
|
||||||
|
// existing Logger. Source code attribution might not work correctly and
|
||||||
|
// unexported fields in Logger get lost.
|
||||||
|
//
|
||||||
|
// Beware that the same LogSink instance may be shared by different logger
|
||||||
|
// instances. Calling functions that modify the LogSink will affect all of
|
||||||
|
// those.
|
||||||
package logr
|
package logr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: consider adding back in format strings if they're really needed
|
// New returns a new Logger instance. This is primarily used by libraries
|
||||||
// TODO: consider other bits of zap/zapcore functionality like ObjectMarshaller (for arbitrary objects)
|
// implementing LogSink, rather than end users.
|
||||||
// TODO: consider other bits of glog functionality like Flush, OutputStats
|
func New(sink LogSink) Logger {
|
||||||
|
logger := Logger{}
|
||||||
// Logger represents the ability to log messages, both errors and not.
|
logger.setSink(sink)
|
||||||
type Logger interface {
|
sink.Init(runtimeInfo)
|
||||||
// Enabled tests whether this Logger is enabled. For example, commandline
|
return logger
|
||||||
// flags might be used to set the logging verbosity and disable some info
|
|
||||||
// logs.
|
|
||||||
Enabled() bool
|
|
||||||
|
|
||||||
// Info logs a non-error message with the given key/value pairs as context.
|
|
||||||
//
|
|
||||||
// The msg argument should be used to add some constant description to
|
|
||||||
// the log line. The key/value pairs can then be used to add additional
|
|
||||||
// variable information. The key/value pairs should alternate string
|
|
||||||
// keys and arbitrary values.
|
|
||||||
Info(msg string, keysAndValues ...interface{})
|
|
||||||
|
|
||||||
// Error logs an error, with the given message and key/value pairs as context.
|
|
||||||
// It functions similarly to calling Info with the "error" named value, but may
|
|
||||||
// have unique behavior, and should be preferred for logging errors (see the
|
|
||||||
// package documentations for more information).
|
|
||||||
//
|
|
||||||
// The msg field should be used to add context to any underlying error,
|
|
||||||
// while the err field should be used to attach the actual error that
|
|
||||||
// triggered this log line, if present.
|
|
||||||
Error(err error, msg string, keysAndValues ...interface{})
|
|
||||||
|
|
||||||
// V returns an Logger value for a specific verbosity level, relative to
|
|
||||||
// this Logger. In other words, V values are additive. V higher verbosity
|
|
||||||
// level means a log message is less important. It's illegal to pass a log
|
|
||||||
// level less than zero.
|
|
||||||
V(level int) Logger
|
|
||||||
|
|
||||||
// WithValues adds some key-value pairs of context to a logger.
|
|
||||||
// See Info for documentation on how key/value pairs work.
|
|
||||||
WithValues(keysAndValues ...interface{}) Logger
|
|
||||||
|
|
||||||
// WithName adds a new element to the logger's name.
|
|
||||||
// Successive calls with WithName continue to append
|
|
||||||
// suffixes to the logger's name. It's strongly recommended
|
|
||||||
// that name segments contain only letters, digits, and hyphens
|
|
||||||
// (see the package documentation for more information).
|
|
||||||
WithName(name string) Logger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// InfoLogger provides compatibility with code that relies on the v0.1.0
|
// setSink stores the sink and updates any related fields. It mutates the
|
||||||
// interface.
|
// logger and thus is only safe to use for loggers that are not currently being
|
||||||
//
|
// used concurrently.
|
||||||
// Deprecated: InfoLogger is an artifact of early versions of this API. New
|
func (l *Logger) setSink(sink LogSink) {
|
||||||
// users should never use it and existing users should use Logger instead. This
|
l.sink = sink
|
||||||
// will be removed in a future release.
|
}
|
||||||
type InfoLogger = Logger
|
|
||||||
|
|
||||||
|
// GetSink returns the stored sink.
|
||||||
|
func (l Logger) GetSink() LogSink {
|
||||||
|
return l.sink
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSink returns a copy of the logger with the new sink.
|
||||||
|
func (l Logger) WithSink(sink LogSink) Logger {
|
||||||
|
l.setSink(sink)
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logger is an interface to an abstract logging implementation. This is a
|
||||||
|
// concrete type for performance reasons, but all the real work is passed on to
|
||||||
|
// a LogSink. Implementations of LogSink should provide their own constructors
|
||||||
|
// that return Logger, not LogSink.
|
||||||
|
//
|
||||||
|
// The underlying sink can be accessed through GetSink and be modified through
|
||||||
|
// WithSink. This enables the implementation of custom extensions (see "Break
|
||||||
|
// Glass" in the package documentation). Normally the sink should be used only
|
||||||
|
// indirectly.
|
||||||
|
type Logger struct {
|
||||||
|
sink LogSink
|
||||||
|
level int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enabled tests whether this Logger is enabled. For example, commandline
|
||||||
|
// flags might be used to set the logging verbosity and disable some info logs.
|
||||||
|
func (l Logger) Enabled() bool {
|
||||||
|
return l.sink.Enabled(l.level)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info logs a non-error message with the given key/value pairs as context.
|
||||||
|
//
|
||||||
|
// The msg argument should be used to add some constant description to the log
|
||||||
|
// line. The key/value pairs can then be used to add additional variable
|
||||||
|
// information. The key/value pairs must alternate string keys and arbitrary
|
||||||
|
// values.
|
||||||
|
func (l Logger) Info(msg string, keysAndValues ...interface{}) {
|
||||||
|
if l.Enabled() {
|
||||||
|
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||||
|
withHelper.GetCallStackHelper()()
|
||||||
|
}
|
||||||
|
l.sink.Info(l.level, msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error logs an error, with the given message and key/value pairs as context.
|
||||||
|
// It functions similarly to Info, but may have unique behavior, and should be
|
||||||
|
// preferred for logging errors (see the package documentations for more
|
||||||
|
// information).
|
||||||
|
//
|
||||||
|
// The msg argument should be used to add context to any underlying error,
|
||||||
|
// while the err argument should be used to attach the actual error that
|
||||||
|
// triggered this log line, if present.
|
||||||
|
func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
|
||||||
|
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||||
|
withHelper.GetCallStackHelper()()
|
||||||
|
}
|
||||||
|
l.sink.Error(err, msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// V returns a new Logger instance for a specific verbosity level, relative to
|
||||||
|
// this Logger. In other words, V-levels are additive. A higher verbosity
|
||||||
|
// level means a log message is less important. Negative V-levels are treated
|
||||||
|
// as 0.
|
||||||
|
func (l Logger) V(level int) Logger {
|
||||||
|
if level < 0 {
|
||||||
|
level = 0
|
||||||
|
}
|
||||||
|
l.level += level
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithValues returns a new Logger instance with additional key/value pairs.
|
||||||
|
// See Info for documentation on how key/value pairs work.
|
||||||
|
func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
|
||||||
|
l.setSink(l.sink.WithValues(keysAndValues...))
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithName returns a new Logger instance with the specified name element added
|
||||||
|
// to the Logger's name. Successive calls with WithName append additional
|
||||||
|
// suffixes to the Logger's name. It's strongly recommended that name segments
|
||||||
|
// contain only letters, digits, and hyphens (see the package documentation for
|
||||||
|
// more information).
|
||||||
|
func (l Logger) WithName(name string) Logger {
|
||||||
|
l.setSink(l.sink.WithName(name))
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCallDepth returns a Logger instance that offsets the call stack by the
|
||||||
|
// specified number of frames when logging call site information, if possible.
|
||||||
|
// This is useful for users who have helper functions between the "real" call
|
||||||
|
// site and the actual calls to Logger methods. If depth is 0 the attribution
|
||||||
|
// should be to the direct caller of this function. If depth is 1 the
|
||||||
|
// attribution should skip 1 call frame, and so on. Successive calls to this
|
||||||
|
// are additive.
|
||||||
|
//
|
||||||
|
// If the underlying log implementation supports a WithCallDepth(int) method,
|
||||||
|
// it will be called and the result returned. If the implementation does not
|
||||||
|
// support CallDepthLogSink, the original Logger will be returned.
|
||||||
|
//
|
||||||
|
// To skip one level, WithCallStackHelper() should be used instead of
|
||||||
|
// WithCallDepth(1) because it works with implementions that support the
|
||||||
|
// CallDepthLogSink and/or CallStackHelperLogSink interfaces.
|
||||||
|
func (l Logger) WithCallDepth(depth int) Logger {
|
||||||
|
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
|
||||||
|
l.setSink(withCallDepth.WithCallDepth(depth))
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCallStackHelper returns a new Logger instance that skips the direct
|
||||||
|
// caller when logging call site information, if possible. This is useful for
|
||||||
|
// users who have helper functions between the "real" call site and the actual
|
||||||
|
// calls to Logger methods and want to support loggers which depend on marking
|
||||||
|
// each individual helper function, like loggers based on testing.T.
|
||||||
|
//
|
||||||
|
// In addition to using that new logger instance, callers also must call the
|
||||||
|
// returned function.
|
||||||
|
//
|
||||||
|
// If the underlying log implementation supports a WithCallDepth(int) method,
|
||||||
|
// WithCallDepth(1) will be called to produce a new logger. If it supports a
|
||||||
|
// WithCallStackHelper() method, that will be also called. If the
|
||||||
|
// implementation does not support either of these, the original Logger will be
|
||||||
|
// returned.
|
||||||
|
func (l Logger) WithCallStackHelper() (func(), Logger) {
|
||||||
|
var helper func()
|
||||||
|
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
|
||||||
|
l.setSink(withCallDepth.WithCallDepth(1))
|
||||||
|
}
|
||||||
|
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||||
|
helper = withHelper.GetCallStackHelper()
|
||||||
|
} else {
|
||||||
|
helper = func() {}
|
||||||
|
}
|
||||||
|
return helper, l
|
||||||
|
}
|
||||||
|
|
||||||
|
// contextKey is how we find Loggers in a context.Context.
|
||||||
type contextKey struct{}
|
type contextKey struct{}
|
||||||
|
|
||||||
// FromContext returns a Logger constructed from ctx or nil if no
|
// FromContext returns a Logger from ctx or an error if no Logger is found.
|
||||||
// logger details are found.
|
func FromContext(ctx context.Context) (Logger, error) {
|
||||||
func FromContext(ctx context.Context) Logger {
|
|
||||||
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
||||||
return v
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return Logger{}, notFoundError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromContextOrDiscard returns a Logger constructed from ctx or a Logger
|
// notFoundError exists to carry an IsNotFound method.
|
||||||
// that discards all messages if no logger details are found.
|
type notFoundError struct{}
|
||||||
|
|
||||||
|
func (notFoundError) Error() string {
|
||||||
|
return "no logr.Logger was present"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (notFoundError) IsNotFound() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this
|
||||||
|
// returns a Logger that discards all log messages.
|
||||||
func FromContextOrDiscard(ctx context.Context) Logger {
|
func FromContextOrDiscard(ctx context.Context) Logger {
|
||||||
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
||||||
return v
|
return v
|
||||||
@ -217,12 +376,59 @@ func FromContextOrDiscard(ctx context.Context) Logger {
|
|||||||
return Discard()
|
return Discard()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext returns a new context derived from ctx that embeds the Logger.
|
// NewContext returns a new Context, derived from ctx, which carries the
|
||||||
func NewContext(ctx context.Context, l Logger) context.Context {
|
// provided Logger.
|
||||||
return context.WithValue(ctx, contextKey{}, l)
|
func NewContext(ctx context.Context, logger Logger) context.Context {
|
||||||
|
return context.WithValue(ctx, contextKey{}, logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallDepthLogger represents a Logger that knows how to climb the call stack
|
// RuntimeInfo holds information that the logr "core" library knows which
|
||||||
|
// LogSinks might want to know.
|
||||||
|
type RuntimeInfo struct {
|
||||||
|
// CallDepth is the number of call frames the logr library adds between the
|
||||||
|
// end-user and the LogSink. LogSink implementations which choose to print
|
||||||
|
// the original logging site (e.g. file & line) should climb this many
|
||||||
|
// additional frames to find it.
|
||||||
|
CallDepth int
|
||||||
|
}
|
||||||
|
|
||||||
|
// runtimeInfo is a static global. It must not be changed at run time.
|
||||||
|
var runtimeInfo = RuntimeInfo{
|
||||||
|
CallDepth: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogSink represents a logging implementation. End-users will generally not
|
||||||
|
// interact with this type.
|
||||||
|
type LogSink interface {
|
||||||
|
// Init receives optional information about the logr library for LogSink
|
||||||
|
// implementations that need it.
|
||||||
|
Init(info RuntimeInfo)
|
||||||
|
|
||||||
|
// Enabled tests whether this LogSink is enabled at the specified V-level.
|
||||||
|
// For example, commandline flags might be used to set the logging
|
||||||
|
// verbosity and disable some info logs.
|
||||||
|
Enabled(level int) bool
|
||||||
|
|
||||||
|
// Info logs a non-error message with the given key/value pairs as context.
|
||||||
|
// The level argument is provided for optional logging. This method will
|
||||||
|
// only be called when Enabled(level) is true. See Logger.Info for more
|
||||||
|
// details.
|
||||||
|
Info(level int, msg string, keysAndValues ...interface{})
|
||||||
|
|
||||||
|
// Error logs an error, with the given message and key/value pairs as
|
||||||
|
// context. See Logger.Error for more details.
|
||||||
|
Error(err error, msg string, keysAndValues ...interface{})
|
||||||
|
|
||||||
|
// WithValues returns a new LogSink with additional key/value pairs. See
|
||||||
|
// Logger.WithValues for more details.
|
||||||
|
WithValues(keysAndValues ...interface{}) LogSink
|
||||||
|
|
||||||
|
// WithName returns a new LogSink with the specified name appended. See
|
||||||
|
// Logger.WithName for more details.
|
||||||
|
WithName(name string) LogSink
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallDepthLogSink represents a Logger that knows how to climb the call stack
|
||||||
// to identify the original call site and can offset the depth by a specified
|
// to identify the original call site and can offset the depth by a specified
|
||||||
// number of frames. This is useful for users who have helper functions
|
// number of frames. This is useful for users who have helper functions
|
||||||
// between the "real" call site and the actual calls to Logger methods.
|
// between the "real" call site and the actual calls to Logger methods.
|
||||||
@ -232,35 +438,59 @@ func NewContext(ctx context.Context, l Logger) context.Context {
|
|||||||
//
|
//
|
||||||
// This is an optional interface and implementations are not required to
|
// This is an optional interface and implementations are not required to
|
||||||
// support it.
|
// support it.
|
||||||
type CallDepthLogger interface {
|
type CallDepthLogSink interface {
|
||||||
Logger
|
// WithCallDepth returns a LogSink that will offset the call
|
||||||
|
// stack by the specified number of frames when logging call
|
||||||
// WithCallDepth returns a Logger that will offset the call stack by the
|
// site information.
|
||||||
// specified number of frames when logging call site information. If depth
|
//
|
||||||
// is 0 the attribution should be to the direct caller of this method. If
|
// If depth is 0, the LogSink should skip exactly the number
|
||||||
// depth is 1 the attribution should skip 1 call frame, and so on.
|
// of call frames defined in RuntimeInfo.CallDepth when Info
|
||||||
|
// or Error are called, i.e. the attribution should be to the
|
||||||
|
// direct caller of Logger.Info or Logger.Error.
|
||||||
|
//
|
||||||
|
// If depth is 1 the attribution should skip 1 call frame, and so on.
|
||||||
// Successive calls to this are additive.
|
// Successive calls to this are additive.
|
||||||
WithCallDepth(depth int) Logger
|
WithCallDepth(depth int) LogSink
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCallDepth returns a Logger that will offset the call stack by the
|
// CallStackHelperLogSink represents a Logger that knows how to climb
|
||||||
// specified number of frames when logging call site information, if possible.
|
// the call stack to identify the original call site and can skip
|
||||||
// This is useful for users who have helper functions between the "real" call
|
// intermediate helper functions if they mark themselves as
|
||||||
// site and the actual calls to Logger methods. If depth is 0 the attribution
|
// helper. Go's testing package uses that approach.
|
||||||
// should be to the direct caller of this function. If depth is 1 the
|
|
||||||
// attribution should skip 1 call frame, and so on. Successive calls to this
|
|
||||||
// are additive.
|
|
||||||
//
|
//
|
||||||
// If the underlying log implementation supports the CallDepthLogger interface,
|
// This is useful for users who have helper functions between the
|
||||||
// the WithCallDepth method will be called and the result returned. If the
|
// "real" call site and the actual calls to Logger methods.
|
||||||
// implementation does not support CallDepthLogger, the original Logger will be
|
// Implementations that log information about the call site (such as
|
||||||
// returned.
|
// file, function, or line) would otherwise log information about the
|
||||||
|
// intermediate helper functions.
|
||||||
//
|
//
|
||||||
// Callers which care about whether this was supported or not should test for
|
// This is an optional interface and implementations are not required
|
||||||
// CallDepthLogger support themselves.
|
// to support it. Implementations that choose to support this must not
|
||||||
func WithCallDepth(logger Logger, depth int) Logger {
|
// simply implement it as WithCallDepth(1), because
|
||||||
if decorator, ok := logger.(CallDepthLogger); ok {
|
// Logger.WithCallStackHelper will call both methods if they are
|
||||||
return decorator.WithCallDepth(depth)
|
// present. This should only be implemented for LogSinks that actually
|
||||||
}
|
// need it, as with testing.T.
|
||||||
return logger
|
type CallStackHelperLogSink interface {
|
||||||
|
// GetCallStackHelper returns a function that must be called
|
||||||
|
// to mark the direct caller as helper function when logging
|
||||||
|
// call site information.
|
||||||
|
GetCallStackHelper() func()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshaler is an optional interface that logged values may choose to
|
||||||
|
// implement. Loggers with structured output, such as JSON, should
|
||||||
|
// log the object return by the MarshalLog method instead of the
|
||||||
|
// original value.
|
||||||
|
type Marshaler interface {
|
||||||
|
// MarshalLog can be used to:
|
||||||
|
// - ensure that structs are not logged as strings when the original
|
||||||
|
// value has a String method: return a different type without a
|
||||||
|
// String method
|
||||||
|
// - select which fields of a complex type should get logged:
|
||||||
|
// return a simpler struct with fewer fields
|
||||||
|
// - log unexported fields: return a different struct
|
||||||
|
// with exported fields
|
||||||
|
//
|
||||||
|
// It may return any value of any type.
|
||||||
|
MarshalLog() interface{}
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/golang/snappy/go.mod
generated
vendored
1
vendor/github.com/golang/snappy/go.mod
generated
vendored
@ -1 +0,0 @@
|
|||||||
module github.com/golang/snappy
|
|
3
vendor/github.com/google/gofuzz/go.mod
generated
vendored
3
vendor/github.com/google/gofuzz/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
module github.com/google/gofuzz
|
|
||||||
|
|
||||||
go 1.12
|
|
1
vendor/github.com/google/uuid/go.mod
generated
vendored
1
vendor/github.com/google/uuid/go.mod
generated
vendored
@ -1 +0,0 @@
|
|||||||
module github.com/google/uuid
|
|
22
vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.mod
generated
vendored
22
vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.mod
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
module github.com/grpc-ecosystem/go-grpc-middleware
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/go-kit/kit v0.9.0
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0 // indirect
|
|
||||||
github.com/go-stack/stack v1.8.0 // indirect
|
|
||||||
github.com/gogo/protobuf v1.3.2
|
|
||||||
github.com/golang/protobuf v1.3.3
|
|
||||||
github.com/opentracing/opentracing-go v1.1.0
|
|
||||||
github.com/pkg/errors v0.8.1 // indirect
|
|
||||||
github.com/sirupsen/logrus v1.4.2
|
|
||||||
github.com/stretchr/testify v1.4.0
|
|
||||||
go.uber.org/atomic v1.4.0 // indirect
|
|
||||||
go.uber.org/multierr v1.1.0 // indirect
|
|
||||||
go.uber.org/zap v1.10.0
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
|
||||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215 // indirect
|
|
||||||
google.golang.org/grpc v1.29.1
|
|
||||||
)
|
|
||||||
|
|
||||||
go 1.14
|
|
122
vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.sum
generated
vendored
122
vendor/github.com/grpc-ecosystem/go-grpc-middleware/go.sum
generated
vendored
@ -1,122 +0,0 @@
|
|||||||
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
|
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
|
||||||
github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
|
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
|
||||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
|
||||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
|
||||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215 h1:0Uz5jLJQioKgVozXa1gzGbzYxbb/rhQEVvSWxzw5oUs=
|
|
||||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
1
vendor/github.com/hashicorp/errwrap/go.mod
generated
vendored
1
vendor/github.com/hashicorp/errwrap/go.mod
generated
vendored
@ -1 +0,0 @@
|
|||||||
module github.com/hashicorp/errwrap
|
|
1
vendor/github.com/hashicorp/go-cleanhttp/go.mod
generated
vendored
1
vendor/github.com/hashicorp/go-cleanhttp/go.mod
generated
vendored
@ -1 +0,0 @@
|
|||||||
module github.com/hashicorp/go-cleanhttp
|
|
12
vendor/github.com/hashicorp/go-hclog/go.mod
generated
vendored
12
vendor/github.com/hashicorp/go-hclog/go.mod
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
module github.com/hashicorp/go-hclog
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/fatih/color v1.7.0
|
|
||||||
github.com/mattn/go-colorable v0.1.4
|
|
||||||
github.com/mattn/go-isatty v0.0.10
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
||||||
github.com/stretchr/testify v1.2.2
|
|
||||||
)
|
|
||||||
|
|
||||||
go 1.13
|
|
18
vendor/github.com/hashicorp/go-hclog/go.sum
generated
vendored
18
vendor/github.com/hashicorp/go-hclog/go.sum
generated
vendored
@ -1,18 +0,0 @@
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
|
||||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
|
||||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
|
||||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
|
|
||||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user