Drop etcd tests dependency
This commit is contained in:
parent
01760927b8
commit
730c21d386
206
LICENSES/vendor/go.etcd.io/etcd/tests/v3/LICENSE
generated
vendored
206
LICENSES/vendor/go.etcd.io/etcd/tests/v3/LICENSE
generated
vendored
@ -1,206 +0,0 @@
|
||||
= vendor/go.etcd.io/etcd/tests/v3 licensed under: =
|
||||
|
||||
|
||||
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.
|
||||
|
||||
= vendor/go.etcd.io/etcd/tests/v3/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
|
7
go.mod
7
go.mod
@ -232,7 +232,6 @@ replace (
|
||||
github.com/emicklei/go-restful => github.com/emicklei/go-restful v2.9.5+incompatible
|
||||
github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d
|
||||
github.com/envoyproxy/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v0.1.0
|
||||
github.com/etcd-io/gofail => github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca
|
||||
github.com/euank/go-kmsg-parser => github.com/euank/go-kmsg-parser v2.0.0+incompatible
|
||||
github.com/evanphx/json-patch => github.com/evanphx/json-patch v4.11.0+incompatible
|
||||
github.com/exponent-io/jsonpath => github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d
|
||||
@ -334,7 +333,7 @@ replace (
|
||||
github.com/mailru/easyjson => github.com/mailru/easyjson v0.7.6
|
||||
github.com/mattn/go-colorable => github.com/mattn/go-colorable v0.0.9
|
||||
github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.3
|
||||
github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.9
|
||||
github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.7
|
||||
github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369
|
||||
github.com/miekg/dns => github.com/miekg/dns v1.0.14
|
||||
github.com/mindprince/gonvml => github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989
|
||||
@ -362,7 +361,7 @@ replace (
|
||||
github.com/mxk/go-flowrate => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
||||
github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e
|
||||
github.com/nxadm/tail => github.com/nxadm/tail v1.4.4
|
||||
github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.4
|
||||
github.com/onsi/ginkgo => github.com/onsi/ginkgo v1.14.0
|
||||
github.com/onsi/gomega => github.com/onsi/gomega v1.10.1
|
||||
github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0
|
||||
@ -426,11 +425,9 @@ replace (
|
||||
go.etcd.io/etcd/client/pkg/v3 => go.etcd.io/etcd/client/pkg/v3 v3.5.0
|
||||
go.etcd.io/etcd/client/v2 => go.etcd.io/etcd/client/v2 v2.305.0
|
||||
go.etcd.io/etcd/client/v3 => go.etcd.io/etcd/client/v3 v3.5.0
|
||||
go.etcd.io/etcd/etcdutl/v3 => go.etcd.io/etcd/etcdutl/v3 v3.5.0
|
||||
go.etcd.io/etcd/pkg/v3 => go.etcd.io/etcd/pkg/v3 v3.5.0
|
||||
go.etcd.io/etcd/raft/v3 => go.etcd.io/etcd/raft/v3 v3.5.0
|
||||
go.etcd.io/etcd/server/v3 => go.etcd.io/etcd/server/v3 v3.5.0
|
||||
go.etcd.io/etcd/tests/v3 => go.etcd.io/etcd/tests/v3 v3.5.0
|
||||
go.opencensus.io => go.opencensus.io v0.22.3
|
||||
go.opentelemetry.io/contrib => go.opentelemetry.io/contrib v0.20.0
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0
|
||||
|
8
go.sum
8
go.sum
@ -157,7 +157,6 @@ github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
github.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY=
|
||||
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
|
||||
@ -316,7 +315,7 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
@ -364,7 +363,7 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
@ -473,15 +472,12 @@ go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLT
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0 h1:ntrg6vvKRW26JRmHTE0iNlDgYK6JX3hg/4cD62X0ixk=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0 h1:kw2TmO3yFTgE+F0mdKkG7xMxkit2duBDa2Hu6D/HMlw=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0 h1:+uMuHYKKlLUzbW322XrQXbaGM9qiV7vUL+AEPT/KYY4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
|
||||
|
@ -115,7 +115,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@ -295,7 +294,6 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
@ -328,7 +326,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@ -434,15 +431,12 @@ go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLT
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0 h1:ntrg6vvKRW26JRmHTE0iNlDgYK6JX3hg/4cD62X0ixk=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0 h1:kw2TmO3yFTgE+F0mdKkG7xMxkit2duBDa2Hu6D/HMlw=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0 h1:+uMuHYKKlLUzbW322XrQXbaGM9qiV7vUL+AEPT/KYY4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
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=
|
||||
|
@ -19,7 +19,6 @@ require (
|
||||
github.com/google/gofuzz v1.1.0
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/googleapis/gnostic v0.5.5
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/hashicorp/golang-lru v0.5.1
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
|
||||
@ -30,7 +29,8 @@ require (
|
||||
go.etcd.io/etcd/api/v3 v3.5.0
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0
|
||||
go.etcd.io/etcd/client/v3 v3.5.0
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0
|
||||
go.etcd.io/etcd/server/v3 v3.5.0
|
||||
go.uber.org/zap v1.17.0
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
|
6
staging/src/k8s.io/apiserver/go.sum
generated
6
staging/src/k8s.io/apiserver/go.sum
generated
@ -115,7 +115,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@ -289,7 +288,6 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
@ -321,7 +319,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@ -428,15 +425,12 @@ go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLT
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0 h1:ntrg6vvKRW26JRmHTE0iNlDgYK6JX3hg/4cD62X0ixk=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0 h1:kw2TmO3yFTgE+F0mdKkG7xMxkit2duBDa2Hu6D/HMlw=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0 h1:+uMuHYKKlLUzbW322XrQXbaGM9qiV7vUL+AEPT/KYY4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
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=
|
||||
|
6
staging/src/k8s.io/cloud-provider/go.sum
generated
6
staging/src/k8s.io/cloud-provider/go.sum
generated
@ -110,7 +110,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@ -283,7 +282,6 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
@ -316,7 +314,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@ -422,15 +419,12 @@ go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLT
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0 h1:ntrg6vvKRW26JRmHTE0iNlDgYK6JX3hg/4cD62X0ixk=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0 h1:kw2TmO3yFTgE+F0mdKkG7xMxkit2duBDa2Hu6D/HMlw=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0 h1:+uMuHYKKlLUzbW322XrQXbaGM9qiV7vUL+AEPT/KYY4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
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=
|
||||
|
6
staging/src/k8s.io/controller-manager/go.sum
generated
6
staging/src/k8s.io/controller-manager/go.sum
generated
@ -145,7 +145,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
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/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@ -362,7 +361,6 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
@ -404,7 +402,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@ -539,15 +536,12 @@ go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLT
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0 h1:ntrg6vvKRW26JRmHTE0iNlDgYK6JX3hg/4cD62X0ixk=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0 h1:kw2TmO3yFTgE+F0mdKkG7xMxkit2duBDa2Hu6D/HMlw=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0 h1:+uMuHYKKlLUzbW322XrQXbaGM9qiV7vUL+AEPT/KYY4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
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=
|
||||
|
6
staging/src/k8s.io/kube-aggregator/go.sum
generated
6
staging/src/k8s.io/kube-aggregator/go.sum
generated
@ -109,7 +109,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@ -283,7 +282,6 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
@ -317,7 +315,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@ -423,15 +420,12 @@ go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLT
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0 h1:ntrg6vvKRW26JRmHTE0iNlDgYK6JX3hg/4cD62X0ixk=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0 h1:kw2TmO3yFTgE+F0mdKkG7xMxkit2duBDa2Hu6D/HMlw=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0 h1:+uMuHYKKlLUzbW322XrQXbaGM9qiV7vUL+AEPT/KYY4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
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=
|
||||
|
@ -95,7 +95,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
@ -247,7 +246,6 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
@ -276,7 +274,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@ -364,11 +361,9 @@ go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQc
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
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=
|
||||
|
5
staging/src/k8s.io/legacy-cloud-providers/go.sum
generated
5
staging/src/k8s.io/legacy-cloud-providers/go.sum
generated
@ -120,7 +120,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@ -292,7 +291,6 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
@ -324,7 +322,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@ -425,11 +422,9 @@ go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQc
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
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=
|
||||
|
6
staging/src/k8s.io/sample-apiserver/go.sum
generated
6
staging/src/k8s.io/sample-apiserver/go.sum
generated
@ -108,7 +108,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
@ -282,7 +281,6 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
@ -314,7 +312,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@ -420,15 +417,12 @@ go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLT
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/etcdutl/v3 v3.5.0/go.mod h1:o98rKMCibbFAG8QS9KmvlYDGDShmmIbmRE8vSofzYNg=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0 h1:ntrg6vvKRW26JRmHTE0iNlDgYK6JX3hg/4cD62X0ixk=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0 h1:kw2TmO3yFTgE+F0mdKkG7xMxkit2duBDa2Hu6D/HMlw=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0 h1:+uMuHYKKlLUzbW322XrQXbaGM9qiV7vUL+AEPT/KYY4=
|
||||
go.etcd.io/etcd/tests/v3 v3.5.0/go.mod h1:f+mtZ1bE1YPvgKdOJV2BKy4JQW0nAFnQehgOE7+WyJE=
|
||||
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=
|
||||
|
16
vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/settable/doc.go
generated
vendored
16
vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/settable/doc.go
generated
vendored
@ -1,16 +0,0 @@
|
||||
//
|
||||
/*
|
||||
grpc_logsettable contains a thread-safe wrapper around grpc-logging
|
||||
infrastructure.
|
||||
|
||||
The go-grpc assumes that logger can be only configured once as the `SetLoggerV2`
|
||||
method is:
|
||||
```Not mutex-protected, should be called before any gRPC functions.```
|
||||
|
||||
This package allows to supply parent logger once ("before any grpc"), but
|
||||
later change underlying implementation in thread-safe way when needed.
|
||||
|
||||
It's in particular useful for testing, where each testcase might need its own
|
||||
logger.
|
||||
*/
|
||||
package grpc_logsettable
|
99
vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/settable/logsettable.go
generated
vendored
99
vendor/github.com/grpc-ecosystem/go-grpc-middleware/logging/settable/logsettable.go
generated
vendored
@ -1,99 +0,0 @@
|
||||
package grpc_logsettable
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
// SettableLoggerV2 is thread-safe.
|
||||
type SettableLoggerV2 interface {
|
||||
grpclog.LoggerV2
|
||||
// Sets given logger as the underlying implementation.
|
||||
Set(loggerv2 grpclog.LoggerV2)
|
||||
// Sets `discard` logger as the underlying implementation.
|
||||
Reset()
|
||||
}
|
||||
|
||||
// ReplaceGrpcLoggerV2 creates and configures SettableLoggerV2 as grpc logger.
|
||||
func ReplaceGrpcLoggerV2() SettableLoggerV2 {
|
||||
settable := &settableLoggerV2{}
|
||||
settable.Reset()
|
||||
grpclog.SetLoggerV2(settable)
|
||||
return settable
|
||||
}
|
||||
|
||||
// SettableLoggerV2 implements SettableLoggerV2
|
||||
type settableLoggerV2 struct {
|
||||
log grpclog.LoggerV2
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Set(log grpclog.LoggerV2) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.log = log
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Reset() {
|
||||
s.Set(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard))
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) get() grpclog.LoggerV2 {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.log
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Info(args ...interface{}) {
|
||||
s.get().Info(args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Infoln(args ...interface{}) {
|
||||
s.get().Infoln(args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Infof(format string, args ...interface{}) {
|
||||
s.get().Infof(format, args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Warning(args ...interface{}) {
|
||||
s.get().Warning(args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Warningln(args ...interface{}) {
|
||||
s.get().Warningln(args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Warningf(format string, args ...interface{}) {
|
||||
s.get().Warningf(format, args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Error(args ...interface{}) {
|
||||
s.get().Error(args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Errorln(args ...interface{}) {
|
||||
s.get().Errorln(args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Errorf(format string, args ...interface{}) {
|
||||
s.get().Errorf(format, args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Fatal(args ...interface{}) {
|
||||
s.get().Fatal(args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Fatalln(args ...interface{}) {
|
||||
s.get().Fatalln(args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) Fatalf(format string, args ...interface{}) {
|
||||
s.get().Fatalf(format, args)
|
||||
}
|
||||
|
||||
func (s *settableLoggerV2) V(l int) bool {
|
||||
return s.get().V(l)
|
||||
}
|
67
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/assert.go
generated
vendored
67
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/assert.go
generated
vendored
@ -1,67 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func AssertEqual(t *testing.T, e, a interface{}, msg ...string) {
|
||||
t.Helper()
|
||||
if (e == nil || a == nil) && (isNil(e) && isNil(a)) {
|
||||
return
|
||||
}
|
||||
if reflect.DeepEqual(e, a) {
|
||||
return
|
||||
}
|
||||
s := ""
|
||||
if len(msg) > 1 {
|
||||
s = msg[0] + ": "
|
||||
}
|
||||
s = fmt.Sprintf("%sexpected %+v, got %+v", s, e, a)
|
||||
FatalStack(t, s)
|
||||
}
|
||||
|
||||
func AssertNil(t *testing.T, v interface{}) {
|
||||
t.Helper()
|
||||
AssertEqual(t, nil, v)
|
||||
}
|
||||
|
||||
func AssertNotNil(t *testing.T, v interface{}) {
|
||||
t.Helper()
|
||||
if v == nil {
|
||||
t.Fatalf("expected non-nil, got %+v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func AssertTrue(t *testing.T, v bool, msg ...string) {
|
||||
t.Helper()
|
||||
AssertEqual(t, true, v, msg...)
|
||||
}
|
||||
|
||||
func AssertFalse(t *testing.T, v bool, msg ...string) {
|
||||
t.Helper()
|
||||
AssertEqual(t, false, v, msg...)
|
||||
}
|
||||
|
||||
func isNil(v interface{}) bool {
|
||||
if v == nil {
|
||||
return true
|
||||
}
|
||||
rv := reflect.ValueOf(v)
|
||||
return rv.Kind() != reflect.Struct && rv.IsNil()
|
||||
}
|
181
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/leak.go
generated
vendored
181
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/leak.go
generated
vendored
@ -1,181 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TODO: Replace with https://github.com/uber-go/goleak.
|
||||
|
||||
/*
|
||||
CheckLeakedGoroutine verifies tests do not leave any leaky
|
||||
goroutines. It returns true when there are goroutines still
|
||||
running(leaking) after all tests.
|
||||
|
||||
import "go.etcd.io/etcd/client/pkg/v3/testutil"
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
testutil.MustTestMainWithLeakDetection(m)
|
||||
}
|
||||
|
||||
func TestSample(t *testing.T) {
|
||||
RegisterLeakDetection(t)
|
||||
...
|
||||
}
|
||||
*/
|
||||
func CheckLeakedGoroutine() bool {
|
||||
gs := interestingGoroutines()
|
||||
if len(gs) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
stackCount := make(map[string]int)
|
||||
re := regexp.MustCompile(`\(0[0-9a-fx, ]*\)`)
|
||||
for _, g := range gs {
|
||||
// strip out pointer arguments in first function of stack dump
|
||||
normalized := string(re.ReplaceAll([]byte(g), []byte("(...)")))
|
||||
stackCount[normalized]++
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Unexpected goroutines running after all test(s).\n")
|
||||
for stack, count := range stackCount {
|
||||
fmt.Fprintf(os.Stderr, "%d instances of:\n%s\n", count, stack)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// CheckAfterTest returns an error if AfterTest would fail with an error.
|
||||
// Waits for go-routines shutdown for 'd'.
|
||||
func CheckAfterTest(d time.Duration) error {
|
||||
http.DefaultTransport.(*http.Transport).CloseIdleConnections()
|
||||
var bad string
|
||||
// Presence of these goroutines causes immediate test failure.
|
||||
badSubstring := map[string]string{
|
||||
").writeLoop(": "a Transport",
|
||||
"created by net/http/httptest.(*Server).Start": "an httptest.Server",
|
||||
"timeoutHandler": "a TimeoutHandler",
|
||||
"net.(*netFD).connect(": "a timing out dial",
|
||||
").noteClientGone(": "a closenotifier sender",
|
||||
").readLoop(": "a Transport",
|
||||
".grpc": "a gRPC resource",
|
||||
").sendCloseSubstream(": "a stream closing routine",
|
||||
}
|
||||
|
||||
var stacks string
|
||||
begin := time.Now()
|
||||
for time.Since(begin) < d {
|
||||
bad = ""
|
||||
goroutines := interestingGoroutines()
|
||||
if len(goroutines) == 0 {
|
||||
return nil
|
||||
}
|
||||
stacks = strings.Join(goroutines, "\n\n")
|
||||
|
||||
for substr, what := range badSubstring {
|
||||
if strings.Contains(stacks, substr) {
|
||||
bad = what
|
||||
}
|
||||
}
|
||||
// Undesired goroutines found, but goroutines might just still be
|
||||
// shutting down, so give it some time.
|
||||
runtime.Gosched()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
return fmt.Errorf("appears to have leaked %s:\n%s", bad, stacks)
|
||||
}
|
||||
|
||||
// RegisterLeakDetection is a convenient way to register before-and-after code to a test.
|
||||
// If you execute RegisterLeakDetection, you don't need to explicitly register AfterTest.
|
||||
func RegisterLeakDetection(t TB) {
|
||||
if err := CheckAfterTest(10 * time.Millisecond); err != nil {
|
||||
t.Skip("Found leaked goroutined BEFORE test", err)
|
||||
return
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
afterTest(t)
|
||||
})
|
||||
}
|
||||
|
||||
// afterTest is meant to run in a defer that executes after a test completes.
|
||||
// It will detect common goroutine leaks, retrying in case there are goroutines
|
||||
// not synchronously torn down, and fail the test if any goroutines are stuck.
|
||||
func afterTest(t TB) {
|
||||
// If test-failed the leaked goroutines list is hidding the real
|
||||
// source of problem.
|
||||
if !t.Failed() {
|
||||
if err := CheckAfterTest(1 * time.Second); err != nil {
|
||||
t.Errorf("Test %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func interestingGoroutines() (gs []string) {
|
||||
buf := make([]byte, 2<<20)
|
||||
buf = buf[:runtime.Stack(buf, true)]
|
||||
for _, g := range strings.Split(string(buf), "\n\n") {
|
||||
sl := strings.SplitN(g, "\n", 2)
|
||||
if len(sl) != 2 {
|
||||
continue
|
||||
}
|
||||
stack := strings.TrimSpace(sl[1])
|
||||
if stack == "" ||
|
||||
strings.Contains(stack, "sync.(*WaitGroup).Done") ||
|
||||
strings.Contains(stack, "os.(*file).close") ||
|
||||
strings.Contains(stack, "os.(*Process).Release") ||
|
||||
strings.Contains(stack, "created by os/signal.init") ||
|
||||
strings.Contains(stack, "runtime/panic.go") ||
|
||||
strings.Contains(stack, "created by testing.RunTests") ||
|
||||
strings.Contains(stack, "created by testing.runTests") ||
|
||||
strings.Contains(stack, "created by testing.(*T).Run") ||
|
||||
strings.Contains(stack, "testing.Main(") ||
|
||||
strings.Contains(stack, "runtime.goexit") ||
|
||||
strings.Contains(stack, "go.etcd.io/etcd/client/pkg/v3/testutil.interestingGoroutines") ||
|
||||
strings.Contains(stack, "go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop") ||
|
||||
strings.Contains(stack, "github.com/golang/glog.(*loggingT).flushDaemon") ||
|
||||
strings.Contains(stack, "created by runtime.gc") ||
|
||||
strings.Contains(stack, "created by text/template/parse.lex") ||
|
||||
strings.Contains(stack, "runtime.MHeap_Scavenger") ||
|
||||
strings.Contains(stack, "rcrypto/internal/boring.(*PublicKeyRSA).finalize") ||
|
||||
strings.Contains(stack, "net.(*netFD).Close(") ||
|
||||
strings.Contains(stack, "testing.(*T).Run") {
|
||||
continue
|
||||
}
|
||||
gs = append(gs, stack)
|
||||
}
|
||||
sort.Strings(gs)
|
||||
return gs
|
||||
}
|
||||
|
||||
func MustCheckLeakedGoroutine() {
|
||||
http.DefaultTransport.(*http.Transport).CloseIdleConnections()
|
||||
|
||||
CheckAfterTest(5 * time.Second)
|
||||
|
||||
// Let the other goroutines finalize.
|
||||
runtime.Gosched()
|
||||
|
||||
if CheckLeakedGoroutine() {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// MustTestMainWithLeakDetection expands standard m.Run with leaked
|
||||
// goroutines detection.
|
||||
func MustTestMainWithLeakDetection(m *testing.M) {
|
||||
v := m.Run()
|
||||
if v == 0 {
|
||||
MustCheckLeakedGoroutine()
|
||||
}
|
||||
os.Exit(v)
|
||||
}
|
57
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/pauseable_handler.go
generated
vendored
57
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/pauseable_handler.go
generated
vendored
@ -1,57 +0,0 @@
|
||||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type PauseableHandler struct {
|
||||
Next http.Handler
|
||||
mu sync.Mutex
|
||||
paused bool
|
||||
}
|
||||
|
||||
func (ph *PauseableHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
ph.mu.Lock()
|
||||
paused := ph.paused
|
||||
ph.mu.Unlock()
|
||||
if !paused {
|
||||
ph.Next.ServeHTTP(w, r)
|
||||
} else {
|
||||
hj, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
panic("webserver doesn't support hijacking")
|
||||
}
|
||||
conn, _, err := hj.Hijack()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (ph *PauseableHandler) Pause() {
|
||||
ph.mu.Lock()
|
||||
defer ph.mu.Unlock()
|
||||
ph.paused = true
|
||||
}
|
||||
|
||||
func (ph *PauseableHandler) Resume() {
|
||||
ph.mu.Lock()
|
||||
defer ph.mu.Unlock()
|
||||
ph.paused = false
|
||||
}
|
139
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/recorder.go
generated
vendored
139
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/recorder.go
generated
vendored
@ -1,139 +0,0 @@
|
||||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Action struct {
|
||||
Name string
|
||||
Params []interface{}
|
||||
}
|
||||
|
||||
type Recorder interface {
|
||||
// Record publishes an Action (e.g., function call) which will
|
||||
// be reflected by Wait() or Chan()
|
||||
Record(a Action)
|
||||
// Wait waits until at least n Actions are available or returns with error
|
||||
Wait(n int) ([]Action, error)
|
||||
// Action returns immediately available Actions
|
||||
Action() []Action
|
||||
// Chan returns the channel for actions published by Record
|
||||
Chan() <-chan Action
|
||||
}
|
||||
|
||||
// RecorderBuffered appends all Actions to a slice
|
||||
type RecorderBuffered struct {
|
||||
sync.Mutex
|
||||
actions []Action
|
||||
}
|
||||
|
||||
func (r *RecorderBuffered) Record(a Action) {
|
||||
r.Lock()
|
||||
r.actions = append(r.actions, a)
|
||||
r.Unlock()
|
||||
}
|
||||
|
||||
func (r *RecorderBuffered) Action() []Action {
|
||||
r.Lock()
|
||||
cpy := make([]Action, len(r.actions))
|
||||
copy(cpy, r.actions)
|
||||
r.Unlock()
|
||||
return cpy
|
||||
}
|
||||
|
||||
func (r *RecorderBuffered) Wait(n int) (acts []Action, err error) {
|
||||
// legacy racey behavior
|
||||
WaitSchedule()
|
||||
acts = r.Action()
|
||||
if len(acts) < n {
|
||||
err = newLenErr(n, len(acts))
|
||||
}
|
||||
return acts, err
|
||||
}
|
||||
|
||||
func (r *RecorderBuffered) Chan() <-chan Action {
|
||||
ch := make(chan Action)
|
||||
go func() {
|
||||
acts := r.Action()
|
||||
for i := range acts {
|
||||
ch <- acts[i]
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
// RecorderStream writes all Actions to an unbuffered channel
|
||||
type recorderStream struct {
|
||||
ch chan Action
|
||||
waitTimeout time.Duration
|
||||
}
|
||||
|
||||
func NewRecorderStream() Recorder {
|
||||
return NewRecorderStreamWithWaitTimout(time.Duration(5 * time.Second))
|
||||
}
|
||||
|
||||
func NewRecorderStreamWithWaitTimout(waitTimeout time.Duration) Recorder {
|
||||
return &recorderStream{ch: make(chan Action), waitTimeout: waitTimeout}
|
||||
}
|
||||
|
||||
func (r *recorderStream) Record(a Action) {
|
||||
r.ch <- a
|
||||
}
|
||||
|
||||
func (r *recorderStream) Action() (acts []Action) {
|
||||
for {
|
||||
select {
|
||||
case act := <-r.ch:
|
||||
acts = append(acts, act)
|
||||
default:
|
||||
return acts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *recorderStream) Chan() <-chan Action {
|
||||
return r.ch
|
||||
}
|
||||
|
||||
func (r *recorderStream) Wait(n int) ([]Action, error) {
|
||||
acts := make([]Action, n)
|
||||
timeoutC := time.After(r.waitTimeout)
|
||||
for i := 0; i < n; i++ {
|
||||
select {
|
||||
case acts[i] = <-r.ch:
|
||||
case <-timeoutC:
|
||||
acts = acts[:i]
|
||||
return acts, newLenErr(n, i)
|
||||
}
|
||||
}
|
||||
// extra wait to catch any Action spew
|
||||
select {
|
||||
case act := <-r.ch:
|
||||
acts = append(acts, act)
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
}
|
||||
return acts, nil
|
||||
}
|
||||
|
||||
func newLenErr(expected int, actual int) error {
|
||||
s := fmt.Sprintf("len(actions) = %d, expected >= %d", actual, expected)
|
||||
return errors.New(s)
|
||||
}
|
130
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/testingtb.go
generated
vendored
130
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/testingtb.go
generated
vendored
@ -1,130 +0,0 @@
|
||||
// Copyright 2021 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// TB is a subset of methods of testing.TB interface.
|
||||
// We cannot implement testing.TB due to protection, so we expose this simplified interface.
|
||||
type TB interface {
|
||||
Cleanup(func())
|
||||
Error(args ...interface{})
|
||||
Errorf(format string, args ...interface{})
|
||||
Fail()
|
||||
FailNow()
|
||||
Failed() bool
|
||||
Fatal(args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
Logf(format string, args ...interface{})
|
||||
Name() string
|
||||
TempDir() string
|
||||
Helper()
|
||||
Skip(args ...interface{})
|
||||
}
|
||||
|
||||
// NewTestingTBProthesis creates a fake variant of testing.TB implementation.
|
||||
// It's supposed to be used in contexts were real testing.T is not provided,
|
||||
// e.g. in 'examples'.
|
||||
//
|
||||
// The `closef` goroutine should get executed when tb will not be needed any longer.
|
||||
//
|
||||
// The provided implementation is NOT thread safe (Cleanup() method).
|
||||
func NewTestingTBProthesis(name string) (tb TB, closef func()) {
|
||||
testtb := &testingTBProthesis{name: name}
|
||||
return testtb, testtb.close
|
||||
}
|
||||
|
||||
type testingTBProthesis struct {
|
||||
name string
|
||||
failed bool
|
||||
cleanups []func()
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Helper() {
|
||||
// Ignored
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Skip(args ...interface{}) {
|
||||
t.Log(append([]interface{}{"Skipping due to: "}, args...))
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Cleanup(f func()) {
|
||||
t.cleanups = append(t.cleanups, f)
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Error(args ...interface{}) {
|
||||
log.Println(args...)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Errorf(format string, args ...interface{}) {
|
||||
log.Printf(format, args...)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Fail() {
|
||||
t.failed = true
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) FailNow() {
|
||||
t.failed = true
|
||||
panic("FailNow() called")
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Failed() bool {
|
||||
return t.failed
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Fatal(args ...interface{}) {
|
||||
log.Fatalln(args...)
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Fatalf(format string, args ...interface{}) {
|
||||
log.Fatalf(format, args...)
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Logf(format string, args ...interface{}) {
|
||||
log.Printf(format, args...)
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Log(args ...interface{}) {
|
||||
log.Println(args...)
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) Name() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) TempDir() string {
|
||||
dir, err := ioutil.TempDir("", t.name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.cleanups = append([]func(){func() {
|
||||
t.Logf("Cleaning UP: %v", dir)
|
||||
os.RemoveAll(dir)
|
||||
}}, t.cleanups...)
|
||||
return dir
|
||||
}
|
||||
|
||||
func (t *testingTBProthesis) close() {
|
||||
for i := len(t.cleanups) - 1; i >= 0; i-- {
|
||||
t.cleanups[i]()
|
||||
}
|
||||
}
|
106
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/testutil.go
generated
vendored
106
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/testutil.go
generated
vendored
@ -1,106 +0,0 @@
|
||||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package testutil provides test utility functions.
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// WaitSchedule briefly sleeps in order to invoke the go scheduler.
|
||||
// TODO: improve this when we are able to know the schedule or status of target go-routine.
|
||||
func WaitSchedule() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
func MustNewURLs(t *testing.T, urls []string) []url.URL {
|
||||
if urls == nil {
|
||||
return nil
|
||||
}
|
||||
var us []url.URL
|
||||
for _, url := range urls {
|
||||
u := MustNewURL(t, url)
|
||||
us = append(us, *u)
|
||||
}
|
||||
return us
|
||||
}
|
||||
|
||||
func MustNewURL(t *testing.T, s string) *url.URL {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
t.Fatalf("parse %v error: %v", s, err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// FatalStack helps to fatal the test and print out the stacks of all running goroutines.
|
||||
func FatalStack(t *testing.T, s string) {
|
||||
stackTrace := make([]byte, 1024*1024)
|
||||
n := runtime.Stack(stackTrace, true)
|
||||
t.Errorf("---> Test failed: %s", s)
|
||||
t.Error(string(stackTrace[:n]))
|
||||
t.Fatal(s)
|
||||
}
|
||||
|
||||
// ConditionFunc returns true when a condition is met.
|
||||
type ConditionFunc func() (bool, error)
|
||||
|
||||
// Poll calls a condition function repeatedly on a polling interval until it returns true, returns an error
|
||||
// or the timeout is reached. If the condition function returns true or an error before the timeout, Poll
|
||||
// immediately returns with the true value or the error. If the timeout is exceeded, Poll returns false.
|
||||
func Poll(interval time.Duration, timeout time.Duration, condition ConditionFunc) (bool, error) {
|
||||
timeoutCh := time.After(timeout)
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timeoutCh:
|
||||
return false, nil
|
||||
case <-ticker.C:
|
||||
success, err := condition()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if success {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SkipTestIfShortMode(t TB, reason string) {
|
||||
if t != nil {
|
||||
t.Helper()
|
||||
if testing.Short() {
|
||||
t.Skip(reason)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ExitInShortMode closes the current process (with 0) if the short test mode detected.
|
||||
//
|
||||
// To be used in Test-main, where test context (testing.TB) is not available.
|
||||
//
|
||||
// Requires custom env-variable (GOLANG_TEST_SHORT) apart of `go test --short flag`.
|
||||
func ExitInShortMode(reason string) {
|
||||
if os.Getenv("GOLANG_TEST_SHORT") == "true" {
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
22
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/var.go
generated
vendored
22
vendor/go.etcd.io/etcd/client/pkg/v3/testutil/var.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
// Copyright 2018 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testutil
|
||||
|
||||
import "time"
|
||||
|
||||
var (
|
||||
ApplyTimeout = time.Second
|
||||
RequestTimeout = 3 * time.Second
|
||||
)
|
43
vendor/go.etcd.io/etcd/client/v3/namespace/doc.go
generated
vendored
43
vendor/go.etcd.io/etcd/client/v3/namespace/doc.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package namespace is a clientv3 wrapper that translates all keys to begin
|
||||
// with a given prefix.
|
||||
//
|
||||
// First, create a client:
|
||||
//
|
||||
// cli, err := clientv3.New(clientv3.Config{Endpoints: []string{"localhost:2379"}})
|
||||
// if err != nil {
|
||||
// // handle error!
|
||||
// }
|
||||
//
|
||||
// Next, override the client interfaces:
|
||||
//
|
||||
// unprefixedKV := cli.KV
|
||||
// cli.KV = namespace.NewKV(cli.KV, "my-prefix/")
|
||||
// cli.Watcher = namespace.NewWatcher(cli.Watcher, "my-prefix/")
|
||||
// cli.Lease = namespace.NewLease(cli.Lease, "my-prefix/")
|
||||
//
|
||||
// Now calls using 'cli' will namespace / prefix all keys with "my-prefix/":
|
||||
//
|
||||
// cli.Put(context.TODO(), "abc", "123")
|
||||
// resp, _ := unprefixedKV.Get(context.TODO(), "my-prefix/abc")
|
||||
// fmt.Printf("%s\n", resp.Kvs[0].Value)
|
||||
// // Output: 123
|
||||
// unprefixedKV.Put(context.TODO(), "my-prefix/abc", "456")
|
||||
// resp, _ = cli.Get(context.TODO(), "abc")
|
||||
// fmt.Printf("%s\n", resp.Kvs[0].Value)
|
||||
// // Output: 456
|
||||
//
|
||||
package namespace
|
206
vendor/go.etcd.io/etcd/client/v3/namespace/kv.go
generated
vendored
206
vendor/go.etcd.io/etcd/client/v3/namespace/kv.go
generated
vendored
@ -1,206 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package namespace
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
type kvPrefix struct {
|
||||
clientv3.KV
|
||||
pfx string
|
||||
}
|
||||
|
||||
// NewKV wraps a KV instance so that all requests
|
||||
// are prefixed with a given string.
|
||||
func NewKV(kv clientv3.KV, prefix string) clientv3.KV {
|
||||
return &kvPrefix{kv, prefix}
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) {
|
||||
if len(key) == 0 {
|
||||
return nil, rpctypes.ErrEmptyKey
|
||||
}
|
||||
op := kv.prefixOp(clientv3.OpPut(key, val, opts...))
|
||||
r, err := kv.KV.Do(ctx, op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
put := r.Put()
|
||||
kv.unprefixPutResponse(put)
|
||||
return put, nil
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error) {
|
||||
if len(key) == 0 && !(clientv3.IsOptsWithFromKey(opts) || clientv3.IsOptsWithPrefix(opts)) {
|
||||
return nil, rpctypes.ErrEmptyKey
|
||||
}
|
||||
r, err := kv.KV.Do(ctx, kv.prefixOp(clientv3.OpGet(key, opts...)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
get := r.Get()
|
||||
kv.unprefixGetResponse(get)
|
||||
return get, nil
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) Delete(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.DeleteResponse, error) {
|
||||
if len(key) == 0 && !(clientv3.IsOptsWithFromKey(opts) || clientv3.IsOptsWithPrefix(opts)) {
|
||||
return nil, rpctypes.ErrEmptyKey
|
||||
}
|
||||
r, err := kv.KV.Do(ctx, kv.prefixOp(clientv3.OpDelete(key, opts...)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
del := r.Del()
|
||||
kv.unprefixDeleteResponse(del)
|
||||
return del, nil
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) Do(ctx context.Context, op clientv3.Op) (clientv3.OpResponse, error) {
|
||||
if len(op.KeyBytes()) == 0 && !op.IsTxn() {
|
||||
return clientv3.OpResponse{}, rpctypes.ErrEmptyKey
|
||||
}
|
||||
r, err := kv.KV.Do(ctx, kv.prefixOp(op))
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
switch {
|
||||
case r.Get() != nil:
|
||||
kv.unprefixGetResponse(r.Get())
|
||||
case r.Put() != nil:
|
||||
kv.unprefixPutResponse(r.Put())
|
||||
case r.Del() != nil:
|
||||
kv.unprefixDeleteResponse(r.Del())
|
||||
case r.Txn() != nil:
|
||||
kv.unprefixTxnResponse(r.Txn())
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
type txnPrefix struct {
|
||||
clientv3.Txn
|
||||
kv *kvPrefix
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) Txn(ctx context.Context) clientv3.Txn {
|
||||
return &txnPrefix{kv.KV.Txn(ctx), kv}
|
||||
}
|
||||
|
||||
func (txn *txnPrefix) If(cs ...clientv3.Cmp) clientv3.Txn {
|
||||
txn.Txn = txn.Txn.If(txn.kv.prefixCmps(cs)...)
|
||||
return txn
|
||||
}
|
||||
|
||||
func (txn *txnPrefix) Then(ops ...clientv3.Op) clientv3.Txn {
|
||||
txn.Txn = txn.Txn.Then(txn.kv.prefixOps(ops)...)
|
||||
return txn
|
||||
}
|
||||
|
||||
func (txn *txnPrefix) Else(ops ...clientv3.Op) clientv3.Txn {
|
||||
txn.Txn = txn.Txn.Else(txn.kv.prefixOps(ops)...)
|
||||
return txn
|
||||
}
|
||||
|
||||
func (txn *txnPrefix) Commit() (*clientv3.TxnResponse, error) {
|
||||
resp, err := txn.Txn.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
txn.kv.unprefixTxnResponse(resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) prefixOp(op clientv3.Op) clientv3.Op {
|
||||
if !op.IsTxn() {
|
||||
begin, end := kv.prefixInterval(op.KeyBytes(), op.RangeBytes())
|
||||
op.WithKeyBytes(begin)
|
||||
op.WithRangeBytes(end)
|
||||
return op
|
||||
}
|
||||
cmps, thenOps, elseOps := op.Txn()
|
||||
return clientv3.OpTxn(kv.prefixCmps(cmps), kv.prefixOps(thenOps), kv.prefixOps(elseOps))
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) unprefixGetResponse(resp *clientv3.GetResponse) {
|
||||
for i := range resp.Kvs {
|
||||
resp.Kvs[i].Key = resp.Kvs[i].Key[len(kv.pfx):]
|
||||
}
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) unprefixPutResponse(resp *clientv3.PutResponse) {
|
||||
if resp.PrevKv != nil {
|
||||
resp.PrevKv.Key = resp.PrevKv.Key[len(kv.pfx):]
|
||||
}
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) unprefixDeleteResponse(resp *clientv3.DeleteResponse) {
|
||||
for i := range resp.PrevKvs {
|
||||
resp.PrevKvs[i].Key = resp.PrevKvs[i].Key[len(kv.pfx):]
|
||||
}
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) unprefixTxnResponse(resp *clientv3.TxnResponse) {
|
||||
for _, r := range resp.Responses {
|
||||
switch tv := r.Response.(type) {
|
||||
case *pb.ResponseOp_ResponseRange:
|
||||
if tv.ResponseRange != nil {
|
||||
kv.unprefixGetResponse((*clientv3.GetResponse)(tv.ResponseRange))
|
||||
}
|
||||
case *pb.ResponseOp_ResponsePut:
|
||||
if tv.ResponsePut != nil {
|
||||
kv.unprefixPutResponse((*clientv3.PutResponse)(tv.ResponsePut))
|
||||
}
|
||||
case *pb.ResponseOp_ResponseDeleteRange:
|
||||
if tv.ResponseDeleteRange != nil {
|
||||
kv.unprefixDeleteResponse((*clientv3.DeleteResponse)(tv.ResponseDeleteRange))
|
||||
}
|
||||
case *pb.ResponseOp_ResponseTxn:
|
||||
if tv.ResponseTxn != nil {
|
||||
kv.unprefixTxnResponse((*clientv3.TxnResponse)(tv.ResponseTxn))
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) prefixInterval(key, end []byte) (pfxKey []byte, pfxEnd []byte) {
|
||||
return prefixInterval(kv.pfx, key, end)
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) prefixCmps(cs []clientv3.Cmp) []clientv3.Cmp {
|
||||
newCmps := make([]clientv3.Cmp, len(cs))
|
||||
for i := range cs {
|
||||
newCmps[i] = cs[i]
|
||||
pfxKey, endKey := kv.prefixInterval(cs[i].KeyBytes(), cs[i].RangeEnd)
|
||||
newCmps[i].WithKeyBytes(pfxKey)
|
||||
if len(cs[i].RangeEnd) != 0 {
|
||||
newCmps[i].RangeEnd = endKey
|
||||
}
|
||||
}
|
||||
return newCmps
|
||||
}
|
||||
|
||||
func (kv *kvPrefix) prefixOps(ops []clientv3.Op) []clientv3.Op {
|
||||
newOps := make([]clientv3.Op, len(ops))
|
||||
for i := range ops {
|
||||
newOps[i] = kv.prefixOp(ops[i])
|
||||
}
|
||||
return newOps
|
||||
}
|
57
vendor/go.etcd.io/etcd/client/v3/namespace/lease.go
generated
vendored
57
vendor/go.etcd.io/etcd/client/v3/namespace/lease.go
generated
vendored
@ -1,57 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package namespace
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
type leasePrefix struct {
|
||||
clientv3.Lease
|
||||
pfx []byte
|
||||
}
|
||||
|
||||
// NewLease wraps a Lease interface to filter for only keys with a prefix
|
||||
// and remove that prefix when fetching attached keys through TimeToLive.
|
||||
func NewLease(l clientv3.Lease, prefix string) clientv3.Lease {
|
||||
return &leasePrefix{l, []byte(prefix)}
|
||||
}
|
||||
|
||||
func (l *leasePrefix) TimeToLive(ctx context.Context, id clientv3.LeaseID, opts ...clientv3.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error) {
|
||||
resp, err := l.Lease.TimeToLive(ctx, id, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(resp.Keys) > 0 {
|
||||
var outKeys [][]byte
|
||||
for i := range resp.Keys {
|
||||
if len(resp.Keys[i]) < len(l.pfx) {
|
||||
// too short
|
||||
continue
|
||||
}
|
||||
if !bytes.Equal(resp.Keys[i][:len(l.pfx)], l.pfx) {
|
||||
// doesn't match prefix
|
||||
continue
|
||||
}
|
||||
// strip prefix
|
||||
outKeys = append(outKeys, resp.Keys[i][len(l.pfx):])
|
||||
}
|
||||
resp.Keys = outKeys
|
||||
}
|
||||
return resp, nil
|
||||
}
|
42
vendor/go.etcd.io/etcd/client/v3/namespace/util.go
generated
vendored
42
vendor/go.etcd.io/etcd/client/v3/namespace/util.go
generated
vendored
@ -1,42 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package namespace
|
||||
|
||||
func prefixInterval(pfx string, key, end []byte) (pfxKey []byte, pfxEnd []byte) {
|
||||
pfxKey = make([]byte, len(pfx)+len(key))
|
||||
copy(pfxKey[copy(pfxKey, pfx):], key)
|
||||
|
||||
if len(end) == 1 && end[0] == 0 {
|
||||
// the edge of the keyspace
|
||||
pfxEnd = make([]byte, len(pfx))
|
||||
copy(pfxEnd, pfx)
|
||||
ok := false
|
||||
for i := len(pfxEnd) - 1; i >= 0; i-- {
|
||||
if pfxEnd[i]++; pfxEnd[i] != 0 {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
// 0xff..ff => 0x00
|
||||
pfxEnd = []byte{0}
|
||||
}
|
||||
} else if len(end) >= 1 {
|
||||
pfxEnd = make([]byte, len(pfx)+len(end))
|
||||
copy(pfxEnd[copy(pfxEnd, pfx):], end)
|
||||
}
|
||||
|
||||
return pfxKey, pfxEnd
|
||||
}
|
83
vendor/go.etcd.io/etcd/client/v3/namespace/watch.go
generated
vendored
83
vendor/go.etcd.io/etcd/client/v3/namespace/watch.go
generated
vendored
@ -1,83 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package namespace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
type watcherPrefix struct {
|
||||
clientv3.Watcher
|
||||
pfx string
|
||||
|
||||
wg sync.WaitGroup
|
||||
stopc chan struct{}
|
||||
stopOnce sync.Once
|
||||
}
|
||||
|
||||
// NewWatcher wraps a Watcher instance so that all Watch requests
|
||||
// are prefixed with a given string and all Watch responses have
|
||||
// the prefix removed.
|
||||
func NewWatcher(w clientv3.Watcher, prefix string) clientv3.Watcher {
|
||||
return &watcherPrefix{Watcher: w, pfx: prefix, stopc: make(chan struct{})}
|
||||
}
|
||||
|
||||
func (w *watcherPrefix) Watch(ctx context.Context, key string, opts ...clientv3.OpOption) clientv3.WatchChan {
|
||||
// since OpOption is opaque, determine range for prefixing through an OpGet
|
||||
op := clientv3.OpGet(key, opts...)
|
||||
end := op.RangeBytes()
|
||||
pfxBegin, pfxEnd := prefixInterval(w.pfx, []byte(key), end)
|
||||
if pfxEnd != nil {
|
||||
opts = append(opts, clientv3.WithRange(string(pfxEnd)))
|
||||
}
|
||||
|
||||
wch := w.Watcher.Watch(ctx, string(pfxBegin), opts...)
|
||||
|
||||
// translate watch events from prefixed to unprefixed
|
||||
pfxWch := make(chan clientv3.WatchResponse)
|
||||
w.wg.Add(1)
|
||||
go func() {
|
||||
defer func() {
|
||||
close(pfxWch)
|
||||
w.wg.Done()
|
||||
}()
|
||||
for wr := range wch {
|
||||
for i := range wr.Events {
|
||||
wr.Events[i].Kv.Key = wr.Events[i].Kv.Key[len(w.pfx):]
|
||||
if wr.Events[i].PrevKv != nil {
|
||||
wr.Events[i].PrevKv.Key = wr.Events[i].Kv.Key
|
||||
}
|
||||
}
|
||||
select {
|
||||
case pfxWch <- wr:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-w.stopc:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return pfxWch
|
||||
}
|
||||
|
||||
func (w *watcherPrefix) Close() error {
|
||||
err := w.Watcher.Close()
|
||||
w.stopOnce.Do(func() { close(w.stopc) })
|
||||
w.wg.Wait()
|
||||
return err
|
||||
}
|
82
vendor/go.etcd.io/etcd/client/v3/naming/endpoints/endpoints.go
generated
vendored
82
vendor/go.etcd.io/etcd/client/v3/naming/endpoints/endpoints.go
generated
vendored
@ -1,82 +0,0 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
// Endpoint represents a single address the connection can be established with.
|
||||
//
|
||||
// Inspired by: https://pkg.go.dev/google.golang.org/grpc/resolver#Address.
|
||||
// Please document etcd version since which version each field is supported.
|
||||
type Endpoint struct {
|
||||
// Addr is the server address on which a connection will be established.
|
||||
// Since etcd 3.1
|
||||
Addr string
|
||||
|
||||
// Metadata is the information associated with Addr, which may be used
|
||||
// to make load balancing decision.
|
||||
// Since etcd 3.1
|
||||
Metadata interface{}
|
||||
}
|
||||
|
||||
type Operation uint8
|
||||
|
||||
const (
|
||||
// Add indicates an Endpoint is added.
|
||||
Add Operation = iota
|
||||
// Delete indicates an existing address is deleted.
|
||||
Delete
|
||||
)
|
||||
|
||||
// Update describes a single edit action of an Endpoint.
|
||||
type Update struct {
|
||||
// Op - action Add or Delete.
|
||||
Op Operation
|
||||
Key string
|
||||
Endpoint Endpoint
|
||||
}
|
||||
|
||||
// WatchChannel is used to deliver notifications about endpoints updates.
|
||||
type WatchChannel <-chan []*Update
|
||||
|
||||
// Key2EndpointMap maps etcd key into struct describing the endpoint.
|
||||
type Key2EndpointMap map[string]Endpoint
|
||||
|
||||
// UpdateWithOpts describes endpoint update (add or delete) together
|
||||
// with etcd options (e.g. to attach an endpoint to a lease).
|
||||
type UpdateWithOpts struct {
|
||||
Update
|
||||
Opts []clientv3.OpOption
|
||||
}
|
||||
|
||||
// NewAddUpdateOpts constructs UpdateWithOpts for endpoint registration.
|
||||
func NewAddUpdateOpts(key string, endpoint Endpoint, opts ...clientv3.OpOption) *UpdateWithOpts {
|
||||
return &UpdateWithOpts{Update: Update{Op: Add, Key: key, Endpoint: endpoint}, Opts: opts}
|
||||
}
|
||||
|
||||
// NewDeleteUpdateOpts constructs UpdateWithOpts for endpoint deletion.
|
||||
func NewDeleteUpdateOpts(key string, opts ...clientv3.OpOption) *UpdateWithOpts {
|
||||
return &UpdateWithOpts{Update: Update{Op: Delete, Key: key}, Opts: opts}
|
||||
}
|
||||
|
||||
// Manager can be used to add/remove & inspect endpoints stored in etcd for
|
||||
// a particular target.
|
||||
type Manager interface {
|
||||
// Update allows to atomically add/remove a few endpoints from etcd.
|
||||
Update(ctx context.Context, updates []*UpdateWithOpts) error
|
||||
|
||||
// AddEndpoint registers a single endpoint in etcd.
|
||||
// For more advanced use-cases use the Update method.
|
||||
AddEndpoint(ctx context.Context, key string, endpoint Endpoint, opts ...clientv3.OpOption) error
|
||||
// DeleteEndpoint deletes a single endpoint stored in etcd.
|
||||
// For more advanced use-cases use the Update method.
|
||||
DeleteEndpoint(ctx context.Context, key string, opts ...clientv3.OpOption) error
|
||||
|
||||
// List returns all the endpoints for the current target as a map.
|
||||
List(ctx context.Context) (Key2EndpointMap, error)
|
||||
// NewWatchChannel creates a channel that populates or endpoint updates.
|
||||
// Cancel the 'ctx' to close the watcher.
|
||||
NewWatchChannel(ctx context.Context) (WatchChannel, error)
|
||||
}
|
175
vendor/go.etcd.io/etcd/client/v3/naming/endpoints/endpoints_impl.go
generated
vendored
175
vendor/go.etcd.io/etcd/client/v3/naming/endpoints/endpoints_impl.go
generated
vendored
@ -1,175 +0,0 @@
|
||||
package endpoints
|
||||
|
||||
// TODO: The API is not yet implemented.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/client/v3/naming/endpoints/internal"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type endpointManager struct {
|
||||
// Client is an initialized etcd client.
|
||||
client *clientv3.Client
|
||||
target string
|
||||
}
|
||||
|
||||
// NewManager creates an endpoint manager which implements the interface of 'Manager'.
|
||||
func NewManager(client *clientv3.Client, target string) (Manager, error) {
|
||||
if client == nil {
|
||||
return nil, errors.New("invalid etcd client")
|
||||
}
|
||||
|
||||
if target == "" {
|
||||
return nil, errors.New("invalid target")
|
||||
}
|
||||
|
||||
em := &endpointManager{
|
||||
client: client,
|
||||
target: target,
|
||||
}
|
||||
return em, nil
|
||||
}
|
||||
|
||||
func (m *endpointManager) Update(ctx context.Context, updates []*UpdateWithOpts) (err error) {
|
||||
ops := make([]clientv3.Op, 0, len(updates))
|
||||
for _, update := range updates {
|
||||
if !strings.HasPrefix(update.Key, m.target+"/") {
|
||||
return status.Errorf(codes.InvalidArgument, "endpoints: endpoint key should be prefixed with '%s/' got: '%s'", m.target, update.Key)
|
||||
}
|
||||
|
||||
switch update.Op {
|
||||
case Add:
|
||||
internalUpdate := &internal.Update{
|
||||
Op: internal.Add,
|
||||
Addr: update.Endpoint.Addr,
|
||||
Metadata: update.Endpoint.Metadata,
|
||||
}
|
||||
|
||||
var v []byte
|
||||
if v, err = json.Marshal(internalUpdate); err != nil {
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
ops = append(ops, clientv3.OpPut(update.Key, string(v), update.Opts...))
|
||||
case Delete:
|
||||
ops = append(ops, clientv3.OpDelete(update.Key, update.Opts...))
|
||||
default:
|
||||
return status.Error(codes.InvalidArgument, "endpoints: bad update op")
|
||||
}
|
||||
}
|
||||
_, err = m.client.KV.Txn(ctx).Then(ops...).Commit()
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *endpointManager) AddEndpoint(ctx context.Context, key string, endpoint Endpoint, opts ...clientv3.OpOption) error {
|
||||
return m.Update(ctx, []*UpdateWithOpts{NewAddUpdateOpts(key, endpoint, opts...)})
|
||||
}
|
||||
|
||||
func (m *endpointManager) DeleteEndpoint(ctx context.Context, key string, opts ...clientv3.OpOption) error {
|
||||
return m.Update(ctx, []*UpdateWithOpts{NewDeleteUpdateOpts(key, opts...)})
|
||||
}
|
||||
|
||||
func (m *endpointManager) NewWatchChannel(ctx context.Context) (WatchChannel, error) {
|
||||
resp, err := m.client.Get(ctx, m.target, clientv3.WithPrefix(), clientv3.WithSerializable())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lg := m.client.GetLogger()
|
||||
initUpdates := make([]*Update, 0, len(resp.Kvs))
|
||||
for _, kv := range resp.Kvs {
|
||||
var iup internal.Update
|
||||
if err := json.Unmarshal(kv.Value, &iup); err != nil {
|
||||
lg.Warn("unmarshal endpoint update failed", zap.String("key", string(kv.Key)), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
up := &Update{
|
||||
Op: Add,
|
||||
Key: string(kv.Key),
|
||||
Endpoint: Endpoint{Addr: iup.Addr, Metadata: iup.Metadata},
|
||||
}
|
||||
initUpdates = append(initUpdates, up)
|
||||
}
|
||||
|
||||
upch := make(chan []*Update, 1)
|
||||
if len(initUpdates) > 0 {
|
||||
upch <- initUpdates
|
||||
}
|
||||
go m.watch(ctx, resp.Header.Revision+1, upch)
|
||||
return upch, nil
|
||||
}
|
||||
|
||||
func (m *endpointManager) watch(ctx context.Context, rev int64, upch chan []*Update) {
|
||||
defer close(upch)
|
||||
|
||||
lg := m.client.GetLogger()
|
||||
opts := []clientv3.OpOption{clientv3.WithRev(rev), clientv3.WithPrefix()}
|
||||
wch := m.client.Watch(ctx, m.target, opts...)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case wresp, ok := <-wch:
|
||||
if !ok {
|
||||
lg.Warn("watch closed", zap.String("target", m.target))
|
||||
return
|
||||
}
|
||||
if wresp.Err() != nil {
|
||||
lg.Warn("watch failed", zap.String("target", m.target), zap.Error(wresp.Err()))
|
||||
return
|
||||
}
|
||||
|
||||
deltaUps := make([]*Update, 0, len(wresp.Events))
|
||||
for _, e := range wresp.Events {
|
||||
var iup internal.Update
|
||||
var err error
|
||||
var op Operation
|
||||
switch e.Type {
|
||||
case clientv3.EventTypePut:
|
||||
err = json.Unmarshal(e.Kv.Value, &iup)
|
||||
op = Add
|
||||
if err != nil {
|
||||
lg.Warn("unmarshal endpoint update failed", zap.String("key", string(e.Kv.Key)), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
case clientv3.EventTypeDelete:
|
||||
iup = internal.Update{Op: internal.Delete}
|
||||
op = Delete
|
||||
default:
|
||||
continue
|
||||
}
|
||||
up := &Update{Op: op, Key: string(e.Kv.Key), Endpoint: Endpoint{Addr: iup.Addr, Metadata: iup.Metadata}}
|
||||
deltaUps = append(deltaUps, up)
|
||||
}
|
||||
if len(deltaUps) > 0 {
|
||||
upch <- deltaUps
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *endpointManager) List(ctx context.Context) (Key2EndpointMap, error) {
|
||||
resp, err := m.client.Get(ctx, m.target, clientv3.WithPrefix(), clientv3.WithSerializable())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eps := make(Key2EndpointMap)
|
||||
for _, kv := range resp.Kvs {
|
||||
var iup internal.Update
|
||||
if err := json.Unmarshal(kv.Value, &iup); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
eps[string(kv.Key)] = Endpoint{Addr: iup.Addr, Metadata: iup.Metadata}
|
||||
}
|
||||
return eps, nil
|
||||
}
|
38
vendor/go.etcd.io/etcd/client/v3/naming/endpoints/internal/update.go
generated
vendored
38
vendor/go.etcd.io/etcd/client/v3/naming/endpoints/internal/update.go
generated
vendored
@ -1,38 +0,0 @@
|
||||
package internal
|
||||
|
||||
// Operation describes action performed on endpoint (addition vs deletion).
|
||||
// Must stay JSON-format compatible with:
|
||||
// https://pkg.go.dev/google.golang.org/grpc@v1.29.1/naming#Operation
|
||||
type Operation uint8
|
||||
|
||||
const (
|
||||
// Add indicates a new address is added.
|
||||
Add Operation = iota
|
||||
// Delete indicates an existing address is deleted.
|
||||
Delete
|
||||
)
|
||||
|
||||
// Update defines a persistent (JSON marshalled) format representing
|
||||
// endpoint within the etcd storage.
|
||||
//
|
||||
// As the format can be persisted by one version of etcd client library and
|
||||
// read by other the format must be kept backward compatible and
|
||||
// in particular must be superset of the grpc(<=1.29.1) naming.Update structure:
|
||||
// https://pkg.go.dev/google.golang.org/grpc@v1.29.1/naming#Update
|
||||
//
|
||||
// Please document since which version of etcd-client given property is supported.
|
||||
// Please keep the naming consistent with e.g. https://pkg.go.dev/google.golang.org/grpc/resolver#Address.
|
||||
//
|
||||
// Notice that it is not valid having both empty string Addr and nil Metadata in an Update.
|
||||
type Update struct {
|
||||
// Op indicates the operation of the update.
|
||||
// Since etcd 3.1.
|
||||
Op Operation
|
||||
// Addr is the updated address. It is empty string if there is no address update.
|
||||
// Since etcd 3.1.
|
||||
Addr string
|
||||
// Metadata is the updated metadata. It is nil if there is no metadata update.
|
||||
// Metadata is not required for a custom naming implementation.
|
||||
// Since etcd 3.1.
|
||||
Metadata interface{}
|
||||
}
|
115
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/auth.go
generated
vendored
115
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/auth.go
generated
vendored
@ -1,115 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
type AuthProxy struct {
|
||||
client *clientv3.Client
|
||||
}
|
||||
|
||||
func NewAuthProxy(c *clientv3.Client) pb.AuthServer {
|
||||
return &AuthProxy{client: c}
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).AuthEnable(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).AuthDisable(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) AuthStatus(ctx context.Context, r *pb.AuthStatusRequest) (*pb.AuthStatusResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).AuthStatus(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).Authenticate(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).RoleAdd(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).RoleDelete(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).RoleGet(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).RoleList(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).RoleRevokePermission(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).RoleGrantPermission(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).UserAdd(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).UserDelete(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).UserGet(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).UserList(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).UserGrantRole(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).UserRevokeRole(ctx, r)
|
||||
}
|
||||
|
||||
func (ap *AuthProxy) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
|
||||
conn := ap.client.ActiveConnection()
|
||||
return pb.NewAuthClient(conn).UserChangePassword(ctx, r)
|
||||
}
|
172
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/cache/store.go
generated
vendored
172
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/cache/store.go
generated
vendored
@ -1,172 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package cache exports functionality for efficiently caching and mapping
|
||||
// `RangeRequest`s to corresponding `RangeResponse`s.
|
||||
package cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/groupcache/lru"
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
"go.etcd.io/etcd/pkg/v3/adt"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultMaxEntries = 2048
|
||||
ErrCompacted = rpctypes.ErrGRPCCompacted
|
||||
)
|
||||
|
||||
type Cache interface {
|
||||
Add(req *pb.RangeRequest, resp *pb.RangeResponse)
|
||||
Get(req *pb.RangeRequest) (*pb.RangeResponse, error)
|
||||
Compact(revision int64)
|
||||
Invalidate(key []byte, endkey []byte)
|
||||
Size() int
|
||||
Close()
|
||||
}
|
||||
|
||||
// keyFunc returns the key of a request, which is used to look up its caching response in the cache.
|
||||
func keyFunc(req *pb.RangeRequest) string {
|
||||
// TODO: use marshalTo to reduce allocation
|
||||
b, err := req.Marshal()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func NewCache(maxCacheEntries int) Cache {
|
||||
return &cache{
|
||||
lru: lru.New(maxCacheEntries),
|
||||
cachedRanges: adt.NewIntervalTree(),
|
||||
compactedRev: -1,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cache) Close() {}
|
||||
|
||||
// cache implements Cache
|
||||
type cache struct {
|
||||
mu sync.RWMutex
|
||||
lru *lru.Cache
|
||||
|
||||
// a reverse index for cache invalidation
|
||||
cachedRanges adt.IntervalTree
|
||||
|
||||
compactedRev int64
|
||||
}
|
||||
|
||||
// Add adds the response of a request to the cache if its revision is larger than the compacted revision of the cache.
|
||||
func (c *cache) Add(req *pb.RangeRequest, resp *pb.RangeResponse) {
|
||||
key := keyFunc(req)
|
||||
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if req.Revision > c.compactedRev {
|
||||
c.lru.Add(key, resp)
|
||||
}
|
||||
// we do not need to invalidate a request with a revision specified.
|
||||
// so we do not need to add it into the reverse index.
|
||||
if req.Revision != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
iv *adt.IntervalValue
|
||||
ivl adt.Interval
|
||||
)
|
||||
if len(req.RangeEnd) != 0 {
|
||||
ivl = adt.NewStringAffineInterval(string(req.Key), string(req.RangeEnd))
|
||||
} else {
|
||||
ivl = adt.NewStringAffinePoint(string(req.Key))
|
||||
}
|
||||
|
||||
iv = c.cachedRanges.Find(ivl)
|
||||
|
||||
if iv == nil {
|
||||
val := map[string]struct{}{key: {}}
|
||||
c.cachedRanges.Insert(ivl, val)
|
||||
} else {
|
||||
val := iv.Val.(map[string]struct{})
|
||||
val[key] = struct{}{}
|
||||
iv.Val = val
|
||||
}
|
||||
}
|
||||
|
||||
// Get looks up the caching response for a given request.
|
||||
// Get is also responsible for lazy eviction when accessing compacted entries.
|
||||
func (c *cache) Get(req *pb.RangeRequest) (*pb.RangeResponse, error) {
|
||||
key := keyFunc(req)
|
||||
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if req.Revision > 0 && req.Revision < c.compactedRev {
|
||||
c.lru.Remove(key)
|
||||
return nil, ErrCompacted
|
||||
}
|
||||
|
||||
if resp, ok := c.lru.Get(key); ok {
|
||||
return resp.(*pb.RangeResponse), nil
|
||||
}
|
||||
return nil, errors.New("not exist")
|
||||
}
|
||||
|
||||
// Invalidate invalidates the cache entries that intersecting with the given range from key to endkey.
|
||||
func (c *cache) Invalidate(key, endkey []byte) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
var (
|
||||
ivs []*adt.IntervalValue
|
||||
ivl adt.Interval
|
||||
)
|
||||
if len(endkey) == 0 {
|
||||
ivl = adt.NewStringAffinePoint(string(key))
|
||||
} else {
|
||||
ivl = adt.NewStringAffineInterval(string(key), string(endkey))
|
||||
}
|
||||
|
||||
ivs = c.cachedRanges.Stab(ivl)
|
||||
for _, iv := range ivs {
|
||||
keys := iv.Val.(map[string]struct{})
|
||||
for key := range keys {
|
||||
c.lru.Remove(key)
|
||||
}
|
||||
}
|
||||
// delete after removing all keys since it is destructive to 'ivs'
|
||||
c.cachedRanges.Delete(ivl)
|
||||
}
|
||||
|
||||
// Compact invalidate all caching response before the given rev.
|
||||
// Replace with the invalidation is lazy. The actual removal happens when the entries is accessed.
|
||||
func (c *cache) Compact(revision int64) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if revision > c.compactedRev {
|
||||
c.compactedRev = revision
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cache) Size() int {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
return c.lru.Len()
|
||||
}
|
213
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/cluster.go
generated
vendored
213
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/cluster.go
generated
vendored
@ -1,213 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/client/v3/naming/endpoints"
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// allow maximum 1 retry per second
|
||||
const resolveRetryRate = 1
|
||||
|
||||
type clusterProxy struct {
|
||||
lg *zap.Logger
|
||||
clus clientv3.Cluster
|
||||
ctx context.Context
|
||||
|
||||
// advertise client URL
|
||||
advaddr string
|
||||
prefix string
|
||||
|
||||
em endpoints.Manager
|
||||
|
||||
umu sync.RWMutex
|
||||
umap map[string]endpoints.Endpoint
|
||||
}
|
||||
|
||||
// NewClusterProxy takes optional prefix to fetch grpc-proxy member endpoints.
|
||||
// The returned channel is closed when there is grpc-proxy endpoint registered
|
||||
// and the client's context is canceled so the 'register' loop returns.
|
||||
// TODO: Expand the API to report creation errors
|
||||
func NewClusterProxy(lg *zap.Logger, c *clientv3.Client, advaddr string, prefix string) (pb.ClusterServer, <-chan struct{}) {
|
||||
if lg == nil {
|
||||
lg = zap.NewNop()
|
||||
}
|
||||
|
||||
var em endpoints.Manager
|
||||
if advaddr != "" && prefix != "" {
|
||||
var err error
|
||||
if em, err = endpoints.NewManager(c, prefix); err != nil {
|
||||
lg.Error("failed to provision endpointsManager", zap.String("prefix", prefix), zap.Error(err))
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
cp := &clusterProxy{
|
||||
lg: lg,
|
||||
clus: c.Cluster,
|
||||
ctx: c.Ctx(),
|
||||
|
||||
advaddr: advaddr,
|
||||
prefix: prefix,
|
||||
umap: make(map[string]endpoints.Endpoint),
|
||||
em: em,
|
||||
}
|
||||
|
||||
donec := make(chan struct{})
|
||||
if em != nil {
|
||||
go func() {
|
||||
defer close(donec)
|
||||
cp.establishEndpointWatch(prefix)
|
||||
}()
|
||||
return cp, donec
|
||||
}
|
||||
|
||||
close(donec)
|
||||
return cp, donec
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) establishEndpointWatch(prefix string) {
|
||||
rm := rate.NewLimiter(rate.Limit(resolveRetryRate), resolveRetryRate)
|
||||
for rm.Wait(cp.ctx) == nil {
|
||||
wc, err := cp.em.NewWatchChannel(cp.ctx)
|
||||
if err != nil {
|
||||
cp.lg.Warn("failed to establish endpoint watch", zap.String("prefix", prefix), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
cp.monitor(wc)
|
||||
}
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) monitor(wa endpoints.WatchChannel) {
|
||||
for {
|
||||
select {
|
||||
case <-cp.ctx.Done():
|
||||
cp.lg.Info("watching endpoints interrupted", zap.Error(cp.ctx.Err()))
|
||||
return
|
||||
case updates := <-wa:
|
||||
cp.umu.Lock()
|
||||
for _, up := range updates {
|
||||
switch up.Op {
|
||||
case endpoints.Add:
|
||||
cp.umap[up.Endpoint.Addr] = up.Endpoint
|
||||
case endpoints.Delete:
|
||||
delete(cp.umap, up.Endpoint.Addr)
|
||||
}
|
||||
}
|
||||
cp.umu.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) {
|
||||
if r.IsLearner {
|
||||
return cp.memberAddAsLearner(ctx, r.PeerURLs)
|
||||
}
|
||||
return cp.memberAdd(ctx, r.PeerURLs)
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) memberAdd(ctx context.Context, peerURLs []string) (*pb.MemberAddResponse, error) {
|
||||
mresp, err := cp.clus.MemberAdd(ctx, peerURLs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := (pb.MemberAddResponse)(*mresp)
|
||||
return &resp, err
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) memberAddAsLearner(ctx context.Context, peerURLs []string) (*pb.MemberAddResponse, error) {
|
||||
mresp, err := cp.clus.MemberAddAsLearner(ctx, peerURLs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := (pb.MemberAddResponse)(*mresp)
|
||||
return &resp, err
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) {
|
||||
mresp, err := cp.clus.MemberRemove(ctx, r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := (pb.MemberRemoveResponse)(*mresp)
|
||||
return &resp, err
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest) (*pb.MemberUpdateResponse, error) {
|
||||
mresp, err := cp.clus.MemberUpdate(ctx, r.ID, r.PeerURLs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := (pb.MemberUpdateResponse)(*mresp)
|
||||
return &resp, err
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) membersFromUpdates() ([]*pb.Member, error) {
|
||||
cp.umu.RLock()
|
||||
defer cp.umu.RUnlock()
|
||||
mbs := make([]*pb.Member, 0, len(cp.umap))
|
||||
for addr, upt := range cp.umap {
|
||||
m, err := decodeMeta(fmt.Sprint(upt.Metadata))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mbs = append(mbs, &pb.Member{Name: m.Name, ClientURLs: []string{addr}})
|
||||
}
|
||||
return mbs, nil
|
||||
}
|
||||
|
||||
// MemberList wraps member list API with following rules:
|
||||
// - If 'advaddr' is not empty and 'prefix' is not empty, return registered member lists via resolver
|
||||
// - If 'advaddr' is not empty and 'prefix' is not empty and registered grpc-proxy members haven't been fetched, return the 'advaddr'
|
||||
// - If 'advaddr' is not empty and 'prefix' is empty, return 'advaddr' without forcing it to 'register'
|
||||
// - If 'advaddr' is empty, forward to member list API
|
||||
func (cp *clusterProxy) MemberList(ctx context.Context, r *pb.MemberListRequest) (*pb.MemberListResponse, error) {
|
||||
if cp.advaddr != "" {
|
||||
if cp.prefix != "" {
|
||||
mbs, err := cp.membersFromUpdates()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(mbs) > 0 {
|
||||
return &pb.MemberListResponse{Members: mbs}, nil
|
||||
}
|
||||
}
|
||||
// prefix is empty or no grpc-proxy members haven't been registered
|
||||
hostname, _ := os.Hostname()
|
||||
return &pb.MemberListResponse{Members: []*pb.Member{{Name: hostname, ClientURLs: []string{cp.advaddr}}}}, nil
|
||||
}
|
||||
mresp, err := cp.clus.MemberList(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := (pb.MemberListResponse)(*mresp)
|
||||
return &resp, err
|
||||
}
|
||||
|
||||
func (cp *clusterProxy) MemberPromote(ctx context.Context, r *pb.MemberPromoteRequest) (*pb.MemberPromoteResponse, error) {
|
||||
// TODO: implement
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
16
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/doc.go
generated
vendored
16
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/doc.go
generated
vendored
@ -1,16 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package grpcproxy is an OSI level 7 proxy for etcd v3 API requests.
|
||||
package grpcproxy
|
65
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/election.go
generated
vendored
65
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/election.go
generated
vendored
@ -1,65 +0,0 @@
|
||||
// Copyright 2017 The etcd Lockors
|
||||
//
|
||||
// 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 grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/v3election/v3electionpb"
|
||||
)
|
||||
|
||||
type electionProxy struct {
|
||||
client *clientv3.Client
|
||||
}
|
||||
|
||||
func NewElectionProxy(client *clientv3.Client) v3electionpb.ElectionServer {
|
||||
return &electionProxy{client: client}
|
||||
}
|
||||
|
||||
func (ep *electionProxy) Campaign(ctx context.Context, req *v3electionpb.CampaignRequest) (*v3electionpb.CampaignResponse, error) {
|
||||
return v3electionpb.NewElectionClient(ep.client.ActiveConnection()).Campaign(ctx, req)
|
||||
}
|
||||
|
||||
func (ep *electionProxy) Proclaim(ctx context.Context, req *v3electionpb.ProclaimRequest) (*v3electionpb.ProclaimResponse, error) {
|
||||
return v3electionpb.NewElectionClient(ep.client.ActiveConnection()).Proclaim(ctx, req)
|
||||
}
|
||||
|
||||
func (ep *electionProxy) Leader(ctx context.Context, req *v3electionpb.LeaderRequest) (*v3electionpb.LeaderResponse, error) {
|
||||
return v3electionpb.NewElectionClient(ep.client.ActiveConnection()).Leader(ctx, req)
|
||||
}
|
||||
|
||||
func (ep *electionProxy) Observe(req *v3electionpb.LeaderRequest, s v3electionpb.Election_ObserveServer) error {
|
||||
conn := ep.client.ActiveConnection()
|
||||
ctx, cancel := context.WithCancel(s.Context())
|
||||
defer cancel()
|
||||
sc, err := v3electionpb.NewElectionClient(conn).Observe(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for {
|
||||
rr, err := sc.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = s.Send(rr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ep *electionProxy) Resign(ctx context.Context, req *v3electionpb.ResignRequest) (*v3electionpb.ResignResponse, error) {
|
||||
return v3electionpb.NewElectionClient(ep.client.ActiveConnection()).Resign(ctx, req)
|
||||
}
|
76
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/health.go
generated
vendored
76
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/health.go
generated
vendored
@ -1,76 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/etcdhttp"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// HandleHealth registers health handler on '/health'.
|
||||
func HandleHealth(lg *zap.Logger, mux *http.ServeMux, c *clientv3.Client) {
|
||||
if lg == nil {
|
||||
lg = zap.NewNop()
|
||||
}
|
||||
mux.Handle(etcdhttp.PathHealth, etcdhttp.NewHealthHandler(lg, func(excludedAlarms etcdhttp.AlarmSet) etcdhttp.Health { return checkHealth(c) }))
|
||||
}
|
||||
|
||||
// HandleProxyHealth registers health handler on '/proxy/health'.
|
||||
func HandleProxyHealth(lg *zap.Logger, mux *http.ServeMux, c *clientv3.Client) {
|
||||
if lg == nil {
|
||||
lg = zap.NewNop()
|
||||
}
|
||||
mux.Handle(etcdhttp.PathProxyHealth, etcdhttp.NewHealthHandler(lg, func(excludedAlarms etcdhttp.AlarmSet) etcdhttp.Health { return checkProxyHealth(c) }))
|
||||
}
|
||||
|
||||
func checkHealth(c *clientv3.Client) etcdhttp.Health {
|
||||
h := etcdhttp.Health{Health: "false"}
|
||||
ctx, cancel := context.WithTimeout(c.Ctx(), time.Second)
|
||||
_, err := c.Get(ctx, "a")
|
||||
cancel()
|
||||
if err == nil || err == rpctypes.ErrPermissionDenied {
|
||||
h.Health = "true"
|
||||
} else {
|
||||
h.Reason = fmt.Sprintf("GET ERROR:%s", err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func checkProxyHealth(c *clientv3.Client) etcdhttp.Health {
|
||||
if c == nil {
|
||||
return etcdhttp.Health{Health: "false", Reason: "no connection to proxy"}
|
||||
}
|
||||
h := checkHealth(c)
|
||||
if h.Health != "true" {
|
||||
return h
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(c.Ctx(), time.Second*3)
|
||||
ch := c.Watch(ctx, "a", clientv3.WithCreatedNotify())
|
||||
select {
|
||||
case <-ch:
|
||||
case <-ctx.Done():
|
||||
h.Health = "false"
|
||||
h.Reason = "WATCH TIMEOUT"
|
||||
}
|
||||
cancel()
|
||||
return h
|
||||
}
|
232
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/kv.go
generated
vendored
232
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/kv.go
generated
vendored
@ -1,232 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/proxy/grpcproxy/cache"
|
||||
)
|
||||
|
||||
type kvProxy struct {
|
||||
kv clientv3.KV
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
func NewKvProxy(c *clientv3.Client) (pb.KVServer, <-chan struct{}) {
|
||||
kv := &kvProxy{
|
||||
kv: c.KV,
|
||||
cache: cache.NewCache(cache.DefaultMaxEntries),
|
||||
}
|
||||
donec := make(chan struct{})
|
||||
close(donec)
|
||||
return kv, donec
|
||||
}
|
||||
|
||||
func (p *kvProxy) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
|
||||
if r.Serializable {
|
||||
resp, err := p.cache.Get(r)
|
||||
switch err {
|
||||
case nil:
|
||||
cacheHits.Inc()
|
||||
return resp, nil
|
||||
case cache.ErrCompacted:
|
||||
cacheHits.Inc()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cachedMisses.Inc()
|
||||
}
|
||||
|
||||
resp, err := p.kv.Do(ctx, RangeRequestToOp(r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// cache linearizable as serializable
|
||||
req := *r
|
||||
req.Serializable = true
|
||||
gresp := (*pb.RangeResponse)(resp.Get())
|
||||
p.cache.Add(&req, gresp)
|
||||
cacheKeys.Set(float64(p.cache.Size()))
|
||||
|
||||
return gresp, nil
|
||||
}
|
||||
|
||||
func (p *kvProxy) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
|
||||
p.cache.Invalidate(r.Key, nil)
|
||||
cacheKeys.Set(float64(p.cache.Size()))
|
||||
|
||||
resp, err := p.kv.Do(ctx, PutRequestToOp(r))
|
||||
return (*pb.PutResponse)(resp.Put()), err
|
||||
}
|
||||
|
||||
func (p *kvProxy) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
|
||||
p.cache.Invalidate(r.Key, r.RangeEnd)
|
||||
cacheKeys.Set(float64(p.cache.Size()))
|
||||
|
||||
resp, err := p.kv.Do(ctx, DelRequestToOp(r))
|
||||
return (*pb.DeleteRangeResponse)(resp.Del()), err
|
||||
}
|
||||
|
||||
func (p *kvProxy) txnToCache(reqs []*pb.RequestOp, resps []*pb.ResponseOp) {
|
||||
for i := range resps {
|
||||
switch tv := resps[i].Response.(type) {
|
||||
case *pb.ResponseOp_ResponsePut:
|
||||
p.cache.Invalidate(reqs[i].GetRequestPut().Key, nil)
|
||||
case *pb.ResponseOp_ResponseDeleteRange:
|
||||
rdr := reqs[i].GetRequestDeleteRange()
|
||||
p.cache.Invalidate(rdr.Key, rdr.RangeEnd)
|
||||
case *pb.ResponseOp_ResponseRange:
|
||||
req := *(reqs[i].GetRequestRange())
|
||||
req.Serializable = true
|
||||
p.cache.Add(&req, tv.ResponseRange)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *kvProxy) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
|
||||
op := TxnRequestToOp(r)
|
||||
opResp, err := p.kv.Do(ctx, op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := opResp.Txn()
|
||||
|
||||
// txn may claim an outdated key is updated; be safe and invalidate
|
||||
for _, cmp := range r.Compare {
|
||||
p.cache.Invalidate(cmp.Key, cmp.RangeEnd)
|
||||
}
|
||||
// update any fetched keys
|
||||
if resp.Succeeded {
|
||||
p.txnToCache(r.Success, resp.Responses)
|
||||
} else {
|
||||
p.txnToCache(r.Failure, resp.Responses)
|
||||
}
|
||||
|
||||
cacheKeys.Set(float64(p.cache.Size()))
|
||||
|
||||
return (*pb.TxnResponse)(resp), nil
|
||||
}
|
||||
|
||||
func (p *kvProxy) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) {
|
||||
var opts []clientv3.CompactOption
|
||||
if r.Physical {
|
||||
opts = append(opts, clientv3.WithCompactPhysical())
|
||||
}
|
||||
|
||||
resp, err := p.kv.Compact(ctx, r.Revision, opts...)
|
||||
if err == nil {
|
||||
p.cache.Compact(r.Revision)
|
||||
}
|
||||
|
||||
cacheKeys.Set(float64(p.cache.Size()))
|
||||
|
||||
return (*pb.CompactionResponse)(resp), err
|
||||
}
|
||||
|
||||
func requestOpToOp(union *pb.RequestOp) clientv3.Op {
|
||||
switch tv := union.Request.(type) {
|
||||
case *pb.RequestOp_RequestRange:
|
||||
if tv.RequestRange != nil {
|
||||
return RangeRequestToOp(tv.RequestRange)
|
||||
}
|
||||
case *pb.RequestOp_RequestPut:
|
||||
if tv.RequestPut != nil {
|
||||
return PutRequestToOp(tv.RequestPut)
|
||||
}
|
||||
case *pb.RequestOp_RequestDeleteRange:
|
||||
if tv.RequestDeleteRange != nil {
|
||||
return DelRequestToOp(tv.RequestDeleteRange)
|
||||
}
|
||||
case *pb.RequestOp_RequestTxn:
|
||||
if tv.RequestTxn != nil {
|
||||
return TxnRequestToOp(tv.RequestTxn)
|
||||
}
|
||||
}
|
||||
panic("unknown request")
|
||||
}
|
||||
|
||||
func RangeRequestToOp(r *pb.RangeRequest) clientv3.Op {
|
||||
opts := []clientv3.OpOption{}
|
||||
if len(r.RangeEnd) != 0 {
|
||||
opts = append(opts, clientv3.WithRange(string(r.RangeEnd)))
|
||||
}
|
||||
opts = append(opts, clientv3.WithRev(r.Revision))
|
||||
opts = append(opts, clientv3.WithLimit(r.Limit))
|
||||
opts = append(opts, clientv3.WithSort(
|
||||
clientv3.SortTarget(r.SortTarget),
|
||||
clientv3.SortOrder(r.SortOrder)),
|
||||
)
|
||||
opts = append(opts, clientv3.WithMaxCreateRev(r.MaxCreateRevision))
|
||||
opts = append(opts, clientv3.WithMinCreateRev(r.MinCreateRevision))
|
||||
opts = append(opts, clientv3.WithMaxModRev(r.MaxModRevision))
|
||||
opts = append(opts, clientv3.WithMinModRev(r.MinModRevision))
|
||||
if r.CountOnly {
|
||||
opts = append(opts, clientv3.WithCountOnly())
|
||||
}
|
||||
if r.KeysOnly {
|
||||
opts = append(opts, clientv3.WithKeysOnly())
|
||||
}
|
||||
if r.Serializable {
|
||||
opts = append(opts, clientv3.WithSerializable())
|
||||
}
|
||||
|
||||
return clientv3.OpGet(string(r.Key), opts...)
|
||||
}
|
||||
|
||||
func PutRequestToOp(r *pb.PutRequest) clientv3.Op {
|
||||
opts := []clientv3.OpOption{}
|
||||
opts = append(opts, clientv3.WithLease(clientv3.LeaseID(r.Lease)))
|
||||
if r.IgnoreValue {
|
||||
opts = append(opts, clientv3.WithIgnoreValue())
|
||||
}
|
||||
if r.IgnoreLease {
|
||||
opts = append(opts, clientv3.WithIgnoreLease())
|
||||
}
|
||||
if r.PrevKv {
|
||||
opts = append(opts, clientv3.WithPrevKV())
|
||||
}
|
||||
return clientv3.OpPut(string(r.Key), string(r.Value), opts...)
|
||||
}
|
||||
|
||||
func DelRequestToOp(r *pb.DeleteRangeRequest) clientv3.Op {
|
||||
opts := []clientv3.OpOption{}
|
||||
if len(r.RangeEnd) != 0 {
|
||||
opts = append(opts, clientv3.WithRange(string(r.RangeEnd)))
|
||||
}
|
||||
if r.PrevKv {
|
||||
opts = append(opts, clientv3.WithPrevKV())
|
||||
}
|
||||
return clientv3.OpDelete(string(r.Key), opts...)
|
||||
}
|
||||
|
||||
func TxnRequestToOp(r *pb.TxnRequest) clientv3.Op {
|
||||
cmps := make([]clientv3.Cmp, len(r.Compare))
|
||||
thenops := make([]clientv3.Op, len(r.Success))
|
||||
elseops := make([]clientv3.Op, len(r.Failure))
|
||||
for i := range r.Compare {
|
||||
cmps[i] = (clientv3.Cmp)(*r.Compare[i])
|
||||
}
|
||||
for i := range r.Success {
|
||||
thenops[i] = requestOpToOp(r.Success[i])
|
||||
}
|
||||
for i := range r.Failure {
|
||||
elseops[i] = requestOpToOp(r.Failure[i])
|
||||
}
|
||||
return clientv3.OpTxn(cmps, thenops, elseops)
|
||||
}
|
113
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/leader.go
generated
vendored
113
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/leader.go
generated
vendored
@ -1,113 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
const (
|
||||
lostLeaderKey = "__lostleader" // watched to detect leader loss
|
||||
retryPerSecond = 10
|
||||
)
|
||||
|
||||
type leader struct {
|
||||
ctx context.Context
|
||||
w clientv3.Watcher
|
||||
// mu protects leaderc updates.
|
||||
mu sync.RWMutex
|
||||
leaderc chan struct{}
|
||||
disconnc chan struct{}
|
||||
donec chan struct{}
|
||||
}
|
||||
|
||||
func newLeader(ctx context.Context, w clientv3.Watcher) *leader {
|
||||
l := &leader{
|
||||
ctx: clientv3.WithRequireLeader(ctx),
|
||||
w: w,
|
||||
leaderc: make(chan struct{}),
|
||||
disconnc: make(chan struct{}),
|
||||
donec: make(chan struct{}),
|
||||
}
|
||||
// begin assuming leader is lost
|
||||
close(l.leaderc)
|
||||
go l.recvLoop()
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *leader) recvLoop() {
|
||||
defer close(l.donec)
|
||||
|
||||
limiter := rate.NewLimiter(rate.Limit(retryPerSecond), retryPerSecond)
|
||||
rev := int64(math.MaxInt64 - 2)
|
||||
for limiter.Wait(l.ctx) == nil {
|
||||
wch := l.w.Watch(l.ctx, lostLeaderKey, clientv3.WithRev(rev), clientv3.WithCreatedNotify())
|
||||
cresp, ok := <-wch
|
||||
if !ok {
|
||||
l.loseLeader()
|
||||
continue
|
||||
}
|
||||
if cresp.Err() != nil {
|
||||
l.loseLeader()
|
||||
if clientv3.IsConnCanceled(cresp.Err()) {
|
||||
close(l.disconnc)
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
l.gotLeader()
|
||||
<-wch
|
||||
l.loseLeader()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *leader) loseLeader() {
|
||||
l.mu.RLock()
|
||||
defer l.mu.RUnlock()
|
||||
select {
|
||||
case <-l.leaderc:
|
||||
default:
|
||||
close(l.leaderc)
|
||||
}
|
||||
}
|
||||
|
||||
// gotLeader will force update the leadership status to having a leader.
|
||||
func (l *leader) gotLeader() {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
select {
|
||||
case <-l.leaderc:
|
||||
l.leaderc = make(chan struct{})
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func (l *leader) disconnectNotify() <-chan struct{} { return l.disconnc }
|
||||
|
||||
func (l *leader) stopNotify() <-chan struct{} { return l.donec }
|
||||
|
||||
// lostNotify returns a channel that is closed if there has been
|
||||
// a leader loss not yet followed by a leader reacquire.
|
||||
func (l *leader) lostNotify() <-chan struct{} {
|
||||
l.mu.RLock()
|
||||
defer l.mu.RUnlock()
|
||||
return l.leaderc
|
||||
}
|
384
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/lease.go
generated
vendored
384
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/lease.go
generated
vendored
@ -1,384 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type leaseProxy struct {
|
||||
// leaseClient handles req from LeaseGrant() that requires a lease ID.
|
||||
leaseClient pb.LeaseClient
|
||||
|
||||
lessor clientv3.Lease
|
||||
|
||||
ctx context.Context
|
||||
|
||||
leader *leader
|
||||
|
||||
// mu protects adding outstanding leaseProxyStream through wg.
|
||||
mu sync.RWMutex
|
||||
|
||||
// wg waits until all outstanding leaseProxyStream quit.
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewLeaseProxy(ctx context.Context, c *clientv3.Client) (pb.LeaseServer, <-chan struct{}) {
|
||||
cctx, cancel := context.WithCancel(ctx)
|
||||
lp := &leaseProxy{
|
||||
leaseClient: pb.NewLeaseClient(c.ActiveConnection()),
|
||||
lessor: c.Lease,
|
||||
ctx: cctx,
|
||||
leader: newLeader(cctx, c.Watcher),
|
||||
}
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
defer close(ch)
|
||||
<-lp.leader.stopNotify()
|
||||
lp.mu.Lock()
|
||||
select {
|
||||
case <-lp.ctx.Done():
|
||||
case <-lp.leader.disconnectNotify():
|
||||
cancel()
|
||||
}
|
||||
<-lp.ctx.Done()
|
||||
lp.mu.Unlock()
|
||||
lp.wg.Wait()
|
||||
}()
|
||||
return lp, ch
|
||||
}
|
||||
|
||||
func (lp *leaseProxy) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
|
||||
rp, err := lp.leaseClient.LeaseGrant(ctx, cr, grpc.WaitForReady(true))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lp.leader.gotLeader()
|
||||
return rp, nil
|
||||
}
|
||||
|
||||
func (lp *leaseProxy) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
|
||||
r, err := lp.lessor.Revoke(ctx, clientv3.LeaseID(rr.ID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lp.leader.gotLeader()
|
||||
return (*pb.LeaseRevokeResponse)(r), nil
|
||||
}
|
||||
|
||||
func (lp *leaseProxy) LeaseTimeToLive(ctx context.Context, rr *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
|
||||
var (
|
||||
r *clientv3.LeaseTimeToLiveResponse
|
||||
err error
|
||||
)
|
||||
if rr.Keys {
|
||||
r, err = lp.lessor.TimeToLive(ctx, clientv3.LeaseID(rr.ID), clientv3.WithAttachedKeys())
|
||||
} else {
|
||||
r, err = lp.lessor.TimeToLive(ctx, clientv3.LeaseID(rr.ID))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rp := &pb.LeaseTimeToLiveResponse{
|
||||
Header: r.ResponseHeader,
|
||||
ID: int64(r.ID),
|
||||
TTL: r.TTL,
|
||||
GrantedTTL: r.GrantedTTL,
|
||||
Keys: r.Keys,
|
||||
}
|
||||
return rp, err
|
||||
}
|
||||
|
||||
func (lp *leaseProxy) LeaseLeases(ctx context.Context, rr *pb.LeaseLeasesRequest) (*pb.LeaseLeasesResponse, error) {
|
||||
r, err := lp.lessor.Leases(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
leases := make([]*pb.LeaseStatus, len(r.Leases))
|
||||
for i := range r.Leases {
|
||||
leases[i] = &pb.LeaseStatus{ID: int64(r.Leases[i].ID)}
|
||||
}
|
||||
rp := &pb.LeaseLeasesResponse{
|
||||
Header: r.ResponseHeader,
|
||||
Leases: leases,
|
||||
}
|
||||
return rp, err
|
||||
}
|
||||
|
||||
func (lp *leaseProxy) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) error {
|
||||
lp.mu.Lock()
|
||||
select {
|
||||
case <-lp.ctx.Done():
|
||||
lp.mu.Unlock()
|
||||
return lp.ctx.Err()
|
||||
default:
|
||||
lp.wg.Add(1)
|
||||
}
|
||||
lp.mu.Unlock()
|
||||
|
||||
ctx, cancel := context.WithCancel(stream.Context())
|
||||
lps := leaseProxyStream{
|
||||
stream: stream,
|
||||
lessor: lp.lessor,
|
||||
keepAliveLeases: make(map[int64]*atomicCounter),
|
||||
respc: make(chan *pb.LeaseKeepAliveResponse),
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
}
|
||||
|
||||
errc := make(chan error, 2)
|
||||
|
||||
var lostLeaderC <-chan struct{}
|
||||
if md, ok := metadata.FromOutgoingContext(stream.Context()); ok {
|
||||
v := md[rpctypes.MetadataRequireLeaderKey]
|
||||
if len(v) > 0 && v[0] == rpctypes.MetadataHasLeader {
|
||||
lostLeaderC = lp.leader.lostNotify()
|
||||
// if leader is known to be lost at creation time, avoid
|
||||
// letting events through at all
|
||||
select {
|
||||
case <-lostLeaderC:
|
||||
lp.wg.Done()
|
||||
return rpctypes.ErrNoLeader
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
stopc := make(chan struct{}, 3)
|
||||
go func() {
|
||||
defer func() { stopc <- struct{}{} }()
|
||||
if err := lps.recvLoop(); err != nil {
|
||||
errc <- err
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer func() { stopc <- struct{}{} }()
|
||||
if err := lps.sendLoop(); err != nil {
|
||||
errc <- err
|
||||
}
|
||||
}()
|
||||
|
||||
// tears down LeaseKeepAlive stream if leader goes down or entire leaseProxy is terminated.
|
||||
go func() {
|
||||
defer func() { stopc <- struct{}{} }()
|
||||
select {
|
||||
case <-lostLeaderC:
|
||||
case <-ctx.Done():
|
||||
case <-lp.ctx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
var err error
|
||||
select {
|
||||
case <-stopc:
|
||||
stopc <- struct{}{}
|
||||
case err = <-errc:
|
||||
}
|
||||
cancel()
|
||||
|
||||
// recv/send may only shutdown after function exits;
|
||||
// this goroutine notifies lease proxy that the stream is through
|
||||
go func() {
|
||||
<-stopc
|
||||
<-stopc
|
||||
<-stopc
|
||||
lps.close()
|
||||
close(errc)
|
||||
lp.wg.Done()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-lostLeaderC:
|
||||
return rpctypes.ErrNoLeader
|
||||
case <-lp.leader.disconnectNotify():
|
||||
return status.Error(codes.Canceled, "the client connection is closing")
|
||||
default:
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
type leaseProxyStream struct {
|
||||
stream pb.Lease_LeaseKeepAliveServer
|
||||
|
||||
lessor clientv3.Lease
|
||||
// wg tracks keepAliveLoop goroutines
|
||||
wg sync.WaitGroup
|
||||
// mu protects keepAliveLeases
|
||||
mu sync.RWMutex
|
||||
// keepAliveLeases tracks how many outstanding keepalive requests which need responses are on a lease.
|
||||
keepAliveLeases map[int64]*atomicCounter
|
||||
// respc receives lease keepalive responses from etcd backend
|
||||
respc chan *pb.LeaseKeepAliveResponse
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func (lps *leaseProxyStream) recvLoop() error {
|
||||
for {
|
||||
rr, err := lps.stream.Recv()
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lps.mu.Lock()
|
||||
neededResps, ok := lps.keepAliveLeases[rr.ID]
|
||||
if !ok {
|
||||
neededResps = &atomicCounter{}
|
||||
lps.keepAliveLeases[rr.ID] = neededResps
|
||||
lps.wg.Add(1)
|
||||
go func() {
|
||||
defer lps.wg.Done()
|
||||
if err := lps.keepAliveLoop(rr.ID, neededResps); err != nil {
|
||||
lps.cancel()
|
||||
}
|
||||
}()
|
||||
}
|
||||
neededResps.add(1)
|
||||
lps.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (lps *leaseProxyStream) keepAliveLoop(leaseID int64, neededResps *atomicCounter) error {
|
||||
cctx, ccancel := context.WithCancel(lps.ctx)
|
||||
defer ccancel()
|
||||
respc, err := lps.lessor.KeepAlive(cctx, clientv3.LeaseID(leaseID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// ticker expires when loop hasn't received keepalive within TTL
|
||||
var ticker <-chan time.Time
|
||||
for {
|
||||
select {
|
||||
case <-ticker:
|
||||
lps.mu.Lock()
|
||||
// if there are outstanding keepAlive reqs at the moment of ticker firing,
|
||||
// don't close keepAliveLoop(), let it continuing to process the KeepAlive reqs.
|
||||
if neededResps.get() > 0 {
|
||||
lps.mu.Unlock()
|
||||
ticker = nil
|
||||
continue
|
||||
}
|
||||
delete(lps.keepAliveLeases, leaseID)
|
||||
lps.mu.Unlock()
|
||||
return nil
|
||||
case rp, ok := <-respc:
|
||||
if !ok {
|
||||
lps.mu.Lock()
|
||||
delete(lps.keepAliveLeases, leaseID)
|
||||
lps.mu.Unlock()
|
||||
if neededResps.get() == 0 {
|
||||
return nil
|
||||
}
|
||||
ttlResp, err := lps.lessor.TimeToLive(cctx, clientv3.LeaseID(leaseID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r := &pb.LeaseKeepAliveResponse{
|
||||
Header: ttlResp.ResponseHeader,
|
||||
ID: int64(ttlResp.ID),
|
||||
TTL: ttlResp.TTL,
|
||||
}
|
||||
for neededResps.get() > 0 {
|
||||
select {
|
||||
case lps.respc <- r:
|
||||
neededResps.add(-1)
|
||||
case <-lps.ctx.Done():
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if neededResps.get() == 0 {
|
||||
continue
|
||||
}
|
||||
ticker = time.After(time.Duration(rp.TTL) * time.Second)
|
||||
r := &pb.LeaseKeepAliveResponse{
|
||||
Header: rp.ResponseHeader,
|
||||
ID: int64(rp.ID),
|
||||
TTL: rp.TTL,
|
||||
}
|
||||
lps.replyToClient(r, neededResps)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (lps *leaseProxyStream) replyToClient(r *pb.LeaseKeepAliveResponse, neededResps *atomicCounter) {
|
||||
timer := time.After(500 * time.Millisecond)
|
||||
for neededResps.get() > 0 {
|
||||
select {
|
||||
case lps.respc <- r:
|
||||
neededResps.add(-1)
|
||||
case <-timer:
|
||||
return
|
||||
case <-lps.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (lps *leaseProxyStream) sendLoop() error {
|
||||
for {
|
||||
select {
|
||||
case lrp, ok := <-lps.respc:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if err := lps.stream.Send(lrp); err != nil {
|
||||
return err
|
||||
}
|
||||
case <-lps.ctx.Done():
|
||||
return lps.ctx.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (lps *leaseProxyStream) close() {
|
||||
lps.cancel()
|
||||
lps.wg.Wait()
|
||||
// only close respc channel if all the keepAliveLoop() goroutines have finished
|
||||
// this ensures those goroutines don't send resp to a closed resp channel
|
||||
close(lps.respc)
|
||||
}
|
||||
|
||||
type atomicCounter struct {
|
||||
counter int64
|
||||
}
|
||||
|
||||
func (ac *atomicCounter) add(delta int64) {
|
||||
atomic.AddInt64(&ac.counter, delta)
|
||||
}
|
||||
|
||||
func (ac *atomicCounter) get() int64 {
|
||||
return atomic.LoadInt64(&ac.counter)
|
||||
}
|
38
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/lock.go
generated
vendored
38
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/lock.go
generated
vendored
@ -1,38 +0,0 @@
|
||||
// Copyright 2017 The etcd Lockors
|
||||
//
|
||||
// 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 grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/v3lock/v3lockpb"
|
||||
)
|
||||
|
||||
type lockProxy struct {
|
||||
client *clientv3.Client
|
||||
}
|
||||
|
||||
func NewLockProxy(client *clientv3.Client) v3lockpb.LockServer {
|
||||
return &lockProxy{client: client}
|
||||
}
|
||||
|
||||
func (lp *lockProxy) Lock(ctx context.Context, req *v3lockpb.LockRequest) (*v3lockpb.LockResponse, error) {
|
||||
return v3lockpb.NewLockClient(lp.client.ActiveConnection()).Lock(ctx, req)
|
||||
}
|
||||
|
||||
func (lp *lockProxy) Unlock(ctx context.Context, req *v3lockpb.UnlockRequest) (*v3lockpb.UnlockResponse, error) {
|
||||
return v3lockpb.NewLockClient(lp.client.ActiveConnection()).Unlock(ctx, req)
|
||||
}
|
95
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/maintenance.go
generated
vendored
95
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/maintenance.go
generated
vendored
@ -1,95 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
type maintenanceProxy struct {
|
||||
client *clientv3.Client
|
||||
}
|
||||
|
||||
func NewMaintenanceProxy(c *clientv3.Client) pb.MaintenanceServer {
|
||||
return &maintenanceProxy{
|
||||
client: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *maintenanceProxy) Defragment(ctx context.Context, dr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) {
|
||||
conn := mp.client.ActiveConnection()
|
||||
return pb.NewMaintenanceClient(conn).Defragment(ctx, dr)
|
||||
}
|
||||
|
||||
func (mp *maintenanceProxy) Snapshot(sr *pb.SnapshotRequest, stream pb.Maintenance_SnapshotServer) error {
|
||||
conn := mp.client.ActiveConnection()
|
||||
ctx, cancel := context.WithCancel(stream.Context())
|
||||
defer cancel()
|
||||
|
||||
ctx = withClientAuthToken(ctx, stream.Context())
|
||||
|
||||
sc, err := pb.NewMaintenanceClient(conn).Snapshot(ctx, sr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
rr, err := sc.Recv()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = stream.Send(rr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *maintenanceProxy) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) {
|
||||
conn := mp.client.ActiveConnection()
|
||||
return pb.NewMaintenanceClient(conn).Hash(ctx, r)
|
||||
}
|
||||
|
||||
func (mp *maintenanceProxy) HashKV(ctx context.Context, r *pb.HashKVRequest) (*pb.HashKVResponse, error) {
|
||||
conn := mp.client.ActiveConnection()
|
||||
return pb.NewMaintenanceClient(conn).HashKV(ctx, r)
|
||||
}
|
||||
|
||||
func (mp *maintenanceProxy) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) {
|
||||
conn := mp.client.ActiveConnection()
|
||||
return pb.NewMaintenanceClient(conn).Alarm(ctx, r)
|
||||
}
|
||||
|
||||
func (mp *maintenanceProxy) Status(ctx context.Context, r *pb.StatusRequest) (*pb.StatusResponse, error) {
|
||||
conn := mp.client.ActiveConnection()
|
||||
return pb.NewMaintenanceClient(conn).Status(ctx, r)
|
||||
}
|
||||
|
||||
func (mp *maintenanceProxy) MoveLeader(ctx context.Context, r *pb.MoveLeaderRequest) (*pb.MoveLeaderResponse, error) {
|
||||
conn := mp.client.ActiveConnection()
|
||||
return pb.NewMaintenanceClient(conn).MoveLeader(ctx, r)
|
||||
}
|
||||
|
||||
func (mp *maintenanceProxy) Downgrade(ctx context.Context, r *pb.DowngradeRequest) (*pb.DowngradeResponse, error) {
|
||||
conn := mp.client.ActiveConnection()
|
||||
return pb.NewMaintenanceClient(conn).Downgrade(ctx, r)
|
||||
}
|
121
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/metrics.go
generated
vendored
121
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/metrics.go
generated
vendored
@ -1,121 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/etcdhttp"
|
||||
)
|
||||
|
||||
var (
|
||||
watchersCoalescing = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "etcd",
|
||||
Subsystem: "grpc_proxy",
|
||||
Name: "watchers_coalescing_total",
|
||||
Help: "Total number of current watchers coalescing",
|
||||
})
|
||||
eventsCoalescing = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Namespace: "etcd",
|
||||
Subsystem: "grpc_proxy",
|
||||
Name: "events_coalescing_total",
|
||||
Help: "Total number of events coalescing",
|
||||
})
|
||||
cacheKeys = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "etcd",
|
||||
Subsystem: "grpc_proxy",
|
||||
Name: "cache_keys_total",
|
||||
Help: "Total number of keys/ranges cached",
|
||||
})
|
||||
cacheHits = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "etcd",
|
||||
Subsystem: "grpc_proxy",
|
||||
Name: "cache_hits_total",
|
||||
Help: "Total number of cache hits",
|
||||
})
|
||||
cachedMisses = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "etcd",
|
||||
Subsystem: "grpc_proxy",
|
||||
Name: "cache_misses_total",
|
||||
Help: "Total number of cache misses",
|
||||
})
|
||||
)
|
||||
|
||||
func init() {
|
||||
prometheus.MustRegister(watchersCoalescing)
|
||||
prometheus.MustRegister(eventsCoalescing)
|
||||
prometheus.MustRegister(cacheKeys)
|
||||
prometheus.MustRegister(cacheHits)
|
||||
prometheus.MustRegister(cachedMisses)
|
||||
}
|
||||
|
||||
// HandleMetrics performs a GET request against etcd endpoint and returns '/metrics'.
|
||||
func HandleMetrics(mux *http.ServeMux, c *http.Client, eps []string) {
|
||||
// random shuffle endpoints
|
||||
r := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
|
||||
if len(eps) > 1 {
|
||||
eps = shuffleEndpoints(r, eps)
|
||||
}
|
||||
|
||||
pathMetrics := etcdhttp.PathMetrics
|
||||
mux.HandleFunc(pathMetrics, func(w http.ResponseWriter, r *http.Request) {
|
||||
target := fmt.Sprintf("%s%s", eps[0], pathMetrics)
|
||||
if !strings.HasPrefix(target, "http") {
|
||||
scheme := "http"
|
||||
if r.TLS != nil {
|
||||
scheme = "https"
|
||||
}
|
||||
target = fmt.Sprintf("%s://%s", scheme, target)
|
||||
}
|
||||
|
||||
resp, err := c.Get(target)
|
||||
if err != nil {
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
w.Header().Set("Content-Type", "text/plain; version=0.0.4")
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Fprintf(w, "%s", body)
|
||||
})
|
||||
}
|
||||
|
||||
// HandleProxyMetrics registers metrics handler on '/proxy/metrics'.
|
||||
func HandleProxyMetrics(mux *http.ServeMux) {
|
||||
mux.Handle(etcdhttp.PathProxyMetrics, promhttp.Handler())
|
||||
}
|
||||
|
||||
func shuffleEndpoints(r *rand.Rand, eps []string) []string {
|
||||
// copied from Go 1.9<= rand.Rand.Perm
|
||||
n := len(eps)
|
||||
p := make([]int, n)
|
||||
for i := 0; i < n; i++ {
|
||||
j := r.Intn(i + 1)
|
||||
p[i] = p[j]
|
||||
p[j] = i
|
||||
}
|
||||
neps := make([]string, n)
|
||||
for i, k := range p {
|
||||
neps[i] = eps[k]
|
||||
}
|
||||
return neps
|
||||
}
|
102
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/register.go
generated
vendored
102
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/register.go
generated
vendored
@ -1,102 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/client/v3/concurrency"
|
||||
"go.etcd.io/etcd/client/v3/naming/endpoints"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
// allow maximum 1 retry per second
|
||||
const registerRetryRate = 1
|
||||
|
||||
// Register registers itself as a grpc-proxy server by writing prefixed-key
|
||||
// with session of specified TTL (in seconds). The returned channel is closed
|
||||
// when the client's context is canceled.
|
||||
func Register(lg *zap.Logger, c *clientv3.Client, prefix string, addr string, ttl int) <-chan struct{} {
|
||||
rm := rate.NewLimiter(rate.Limit(registerRetryRate), registerRetryRate)
|
||||
|
||||
donec := make(chan struct{})
|
||||
go func() {
|
||||
defer close(donec)
|
||||
|
||||
for rm.Wait(c.Ctx()) == nil {
|
||||
ss, err := registerSession(lg, c, prefix, addr, ttl)
|
||||
if err != nil {
|
||||
lg.Warn("failed to create a session", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
select {
|
||||
case <-c.Ctx().Done():
|
||||
ss.Close()
|
||||
return
|
||||
|
||||
case <-ss.Done():
|
||||
lg.Warn("session expired; possible network partition or server restart")
|
||||
lg.Warn("creating a new session to rejoin")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return donec
|
||||
}
|
||||
|
||||
func registerSession(lg *zap.Logger, c *clientv3.Client, prefix string, addr string, ttl int) (*concurrency.Session, error) {
|
||||
ss, err := concurrency.NewSession(c, concurrency.WithTTL(ttl))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
em, err := endpoints.NewManager(c, prefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endpoint := endpoints.Endpoint{Addr: addr, Metadata: getMeta()}
|
||||
if err = em.AddEndpoint(c.Ctx(), prefix+"/"+addr, endpoint, clientv3.WithLease(ss.Lease())); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lg.Info(
|
||||
"registered session with lease",
|
||||
zap.String("addr", addr),
|
||||
zap.Int("lease-ttl", ttl),
|
||||
)
|
||||
return ss, nil
|
||||
}
|
||||
|
||||
// meta represents metadata of proxy register.
|
||||
type meta struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func getMeta() string {
|
||||
hostname, _ := os.Hostname()
|
||||
bts, _ := json.Marshal(meta{Name: hostname})
|
||||
return string(bts)
|
||||
}
|
||||
|
||||
func decodeMeta(s string) (meta, error) {
|
||||
m := meta{}
|
||||
err := json.Unmarshal([]byte(s), &m)
|
||||
return m, err
|
||||
}
|
75
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/util.go
generated
vendored
75
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/util.go
generated
vendored
@ -1,75 +0,0 @@
|
||||
// Copyright 2017 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
func getAuthTokenFromClient(ctx context.Context) string {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if ok {
|
||||
ts, ok := md[rpctypes.TokenFieldNameGRPC]
|
||||
if ok {
|
||||
return ts[0]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func withClientAuthToken(ctx, ctxWithToken context.Context) context.Context {
|
||||
token := getAuthTokenFromClient(ctxWithToken)
|
||||
if token != "" {
|
||||
ctx = context.WithValue(ctx, rpctypes.TokenFieldNameGRPC, token)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
type proxyTokenCredential struct {
|
||||
token string
|
||||
}
|
||||
|
||||
func (cred *proxyTokenCredential) RequireTransportSecurity() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (cred *proxyTokenCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) {
|
||||
return map[string]string{
|
||||
rpctypes.TokenFieldNameGRPC: cred.token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func AuthUnaryClientInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
||||
token := getAuthTokenFromClient(ctx)
|
||||
if token != "" {
|
||||
tokenCred := &proxyTokenCredential{token}
|
||||
opts = append(opts, grpc.PerRPCCredentials(tokenCred))
|
||||
}
|
||||
return invoker(ctx, method, req, reply, cc, opts...)
|
||||
}
|
||||
|
||||
func AuthStreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||
tokenif := ctx.Value(rpctypes.TokenFieldNameGRPC)
|
||||
if tokenif != nil {
|
||||
tokenCred := &proxyTokenCredential{tokenif.(string)}
|
||||
opts = append(opts, grpc.PerRPCCredentials(tokenCred))
|
||||
}
|
||||
return streamer(ctx, desc, cc, method, opts...)
|
||||
}
|
313
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watch.go
generated
vendored
313
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watch.go
generated
vendored
@ -1,313 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/v3rpc"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type watchProxy struct {
|
||||
cw clientv3.Watcher
|
||||
ctx context.Context
|
||||
|
||||
leader *leader
|
||||
|
||||
ranges *watchRanges
|
||||
|
||||
// mu protects adding outstanding watch servers through wg.
|
||||
mu sync.Mutex
|
||||
|
||||
// wg waits until all outstanding watch servers quit.
|
||||
wg sync.WaitGroup
|
||||
|
||||
// kv is used for permission checking
|
||||
kv clientv3.KV
|
||||
lg *zap.Logger
|
||||
}
|
||||
|
||||
func NewWatchProxy(ctx context.Context, lg *zap.Logger, c *clientv3.Client) (pb.WatchServer, <-chan struct{}) {
|
||||
cctx, cancel := context.WithCancel(ctx)
|
||||
wp := &watchProxy{
|
||||
cw: c.Watcher,
|
||||
ctx: cctx,
|
||||
leader: newLeader(cctx, c.Watcher),
|
||||
|
||||
kv: c.KV, // for permission checking
|
||||
lg: lg,
|
||||
}
|
||||
wp.ranges = newWatchRanges(wp)
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
defer close(ch)
|
||||
<-wp.leader.stopNotify()
|
||||
wp.mu.Lock()
|
||||
select {
|
||||
case <-wp.ctx.Done():
|
||||
case <-wp.leader.disconnectNotify():
|
||||
cancel()
|
||||
}
|
||||
<-wp.ctx.Done()
|
||||
wp.mu.Unlock()
|
||||
wp.wg.Wait()
|
||||
wp.ranges.stop()
|
||||
}()
|
||||
return wp, ch
|
||||
}
|
||||
|
||||
func (wp *watchProxy) Watch(stream pb.Watch_WatchServer) (err error) {
|
||||
wp.mu.Lock()
|
||||
select {
|
||||
case <-wp.ctx.Done():
|
||||
wp.mu.Unlock()
|
||||
select {
|
||||
case <-wp.leader.disconnectNotify():
|
||||
return status.Error(codes.Canceled, "the client connection is closing")
|
||||
default:
|
||||
return wp.ctx.Err()
|
||||
}
|
||||
default:
|
||||
wp.wg.Add(1)
|
||||
}
|
||||
wp.mu.Unlock()
|
||||
|
||||
ctx, cancel := context.WithCancel(stream.Context())
|
||||
wps := &watchProxyStream{
|
||||
ranges: wp.ranges,
|
||||
watchers: make(map[int64]*watcher),
|
||||
stream: stream,
|
||||
watchCh: make(chan *pb.WatchResponse, 1024),
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
kv: wp.kv,
|
||||
lg: wp.lg,
|
||||
}
|
||||
|
||||
var lostLeaderC <-chan struct{}
|
||||
if md, ok := metadata.FromOutgoingContext(stream.Context()); ok {
|
||||
v := md[rpctypes.MetadataRequireLeaderKey]
|
||||
if len(v) > 0 && v[0] == rpctypes.MetadataHasLeader {
|
||||
lostLeaderC = wp.leader.lostNotify()
|
||||
// if leader is known to be lost at creation time, avoid
|
||||
// letting events through at all
|
||||
select {
|
||||
case <-lostLeaderC:
|
||||
wp.wg.Done()
|
||||
return rpctypes.ErrNoLeader
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// post to stopc => terminate server stream; can't use a waitgroup
|
||||
// since all goroutines will only terminate after Watch() exits.
|
||||
stopc := make(chan struct{}, 3)
|
||||
go func() {
|
||||
defer func() { stopc <- struct{}{} }()
|
||||
wps.recvLoop()
|
||||
}()
|
||||
go func() {
|
||||
defer func() { stopc <- struct{}{} }()
|
||||
wps.sendLoop()
|
||||
}()
|
||||
// tear down watch if leader goes down or entire watch proxy is terminated
|
||||
go func() {
|
||||
defer func() { stopc <- struct{}{} }()
|
||||
select {
|
||||
case <-lostLeaderC:
|
||||
case <-ctx.Done():
|
||||
case <-wp.ctx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
<-stopc
|
||||
cancel()
|
||||
|
||||
// recv/send may only shutdown after function exits;
|
||||
// goroutine notifies proxy that stream is through
|
||||
go func() {
|
||||
<-stopc
|
||||
<-stopc
|
||||
wps.close()
|
||||
wp.wg.Done()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-lostLeaderC:
|
||||
return rpctypes.ErrNoLeader
|
||||
case <-wp.leader.disconnectNotify():
|
||||
return status.Error(codes.Canceled, "the client connection is closing")
|
||||
default:
|
||||
return wps.ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
// watchProxyStream forwards etcd watch events to a proxied client stream.
|
||||
type watchProxyStream struct {
|
||||
ranges *watchRanges
|
||||
|
||||
// mu protects watchers and nextWatcherID
|
||||
mu sync.Mutex
|
||||
// watchers receive events from watch broadcast.
|
||||
watchers map[int64]*watcher
|
||||
// nextWatcherID is the id to assign the next watcher on this stream.
|
||||
nextWatcherID int64
|
||||
|
||||
stream pb.Watch_WatchServer
|
||||
|
||||
// watchCh receives watch responses from the watchers.
|
||||
watchCh chan *pb.WatchResponse
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
|
||||
// kv is used for permission checking
|
||||
kv clientv3.KV
|
||||
lg *zap.Logger
|
||||
}
|
||||
|
||||
func (wps *watchProxyStream) close() {
|
||||
var wg sync.WaitGroup
|
||||
wps.cancel()
|
||||
wps.mu.Lock()
|
||||
wg.Add(len(wps.watchers))
|
||||
for _, wpsw := range wps.watchers {
|
||||
go func(w *watcher) {
|
||||
wps.ranges.delete(w)
|
||||
wg.Done()
|
||||
}(wpsw)
|
||||
}
|
||||
wps.watchers = nil
|
||||
wps.mu.Unlock()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
close(wps.watchCh)
|
||||
}
|
||||
|
||||
func (wps *watchProxyStream) checkPermissionForWatch(key, rangeEnd []byte) error {
|
||||
if len(key) == 0 {
|
||||
// If the length of the key is 0, we need to obtain full range.
|
||||
// look at clientv3.WithPrefix()
|
||||
key = []byte{0}
|
||||
rangeEnd = []byte{0}
|
||||
}
|
||||
req := &pb.RangeRequest{
|
||||
Serializable: true,
|
||||
Key: key,
|
||||
RangeEnd: rangeEnd,
|
||||
CountOnly: true,
|
||||
Limit: 1,
|
||||
}
|
||||
_, err := wps.kv.Do(wps.ctx, RangeRequestToOp(req))
|
||||
return err
|
||||
}
|
||||
|
||||
func (wps *watchProxyStream) recvLoop() error {
|
||||
for {
|
||||
req, err := wps.stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch uv := req.RequestUnion.(type) {
|
||||
case *pb.WatchRequest_CreateRequest:
|
||||
cr := uv.CreateRequest
|
||||
|
||||
if err := wps.checkPermissionForWatch(cr.Key, cr.RangeEnd); err != nil {
|
||||
wps.watchCh <- &pb.WatchResponse{
|
||||
Header: &pb.ResponseHeader{},
|
||||
WatchId: -1,
|
||||
Created: true,
|
||||
Canceled: true,
|
||||
CancelReason: err.Error(),
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
wps.mu.Lock()
|
||||
w := &watcher{
|
||||
wr: watchRange{string(cr.Key), string(cr.RangeEnd)},
|
||||
id: wps.nextWatcherID,
|
||||
wps: wps,
|
||||
|
||||
nextrev: cr.StartRevision,
|
||||
progress: cr.ProgressNotify,
|
||||
prevKV: cr.PrevKv,
|
||||
filters: v3rpc.FiltersFromRequest(cr),
|
||||
}
|
||||
if !w.wr.valid() {
|
||||
w.post(&pb.WatchResponse{WatchId: -1, Created: true, Canceled: true})
|
||||
wps.mu.Unlock()
|
||||
continue
|
||||
}
|
||||
wps.nextWatcherID++
|
||||
w.nextrev = cr.StartRevision
|
||||
wps.watchers[w.id] = w
|
||||
wps.ranges.add(w)
|
||||
wps.mu.Unlock()
|
||||
wps.lg.Debug("create watcher", zap.String("key", w.wr.key), zap.String("end", w.wr.end), zap.Int64("watcherId", wps.nextWatcherID))
|
||||
case *pb.WatchRequest_CancelRequest:
|
||||
wps.delete(uv.CancelRequest.WatchId)
|
||||
wps.lg.Debug("cancel watcher", zap.Int64("watcherId", uv.CancelRequest.WatchId))
|
||||
default:
|
||||
// Panic or Fatalf would allow to network clients to crash the serve remotely.
|
||||
wps.lg.Error("not supported request type by gRPC proxy", zap.Stringer("request", req))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wps *watchProxyStream) sendLoop() {
|
||||
for {
|
||||
select {
|
||||
case wresp, ok := <-wps.watchCh:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if err := wps.stream.Send(wresp); err != nil {
|
||||
return
|
||||
}
|
||||
case <-wps.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wps *watchProxyStream) delete(id int64) {
|
||||
wps.mu.Lock()
|
||||
defer wps.mu.Unlock()
|
||||
|
||||
w, ok := wps.watchers[id]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
wps.ranges.delete(w)
|
||||
delete(wps.watchers, id)
|
||||
resp := &pb.WatchResponse{
|
||||
Header: &w.lastHeader,
|
||||
WatchId: id,
|
||||
Canceled: true,
|
||||
}
|
||||
wps.watchCh <- resp
|
||||
}
|
166
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watch_broadcast.go
generated
vendored
166
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watch_broadcast.go
generated
vendored
@ -1,166 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// watchBroadcast broadcasts a server watcher to many client watchers.
|
||||
type watchBroadcast struct {
|
||||
// cancel stops the underlying etcd server watcher and closes ch.
|
||||
cancel context.CancelFunc
|
||||
donec chan struct{}
|
||||
|
||||
// mu protects rev and receivers.
|
||||
mu sync.RWMutex
|
||||
// nextrev is the minimum expected next revision of the watcher on ch.
|
||||
nextrev int64
|
||||
// receivers contains all the client-side watchers to serve.
|
||||
receivers map[*watcher]struct{}
|
||||
// responses counts the number of responses
|
||||
responses int
|
||||
lg *zap.Logger
|
||||
}
|
||||
|
||||
func newWatchBroadcast(lg *zap.Logger, wp *watchProxy, w *watcher, update func(*watchBroadcast)) *watchBroadcast {
|
||||
cctx, cancel := context.WithCancel(wp.ctx)
|
||||
wb := &watchBroadcast{
|
||||
cancel: cancel,
|
||||
nextrev: w.nextrev,
|
||||
receivers: make(map[*watcher]struct{}),
|
||||
donec: make(chan struct{}),
|
||||
lg: lg,
|
||||
}
|
||||
wb.add(w)
|
||||
go func() {
|
||||
defer close(wb.donec)
|
||||
|
||||
opts := []clientv3.OpOption{
|
||||
clientv3.WithRange(w.wr.end),
|
||||
clientv3.WithProgressNotify(),
|
||||
clientv3.WithRev(wb.nextrev),
|
||||
clientv3.WithPrevKV(),
|
||||
clientv3.WithCreatedNotify(),
|
||||
}
|
||||
|
||||
cctx = withClientAuthToken(cctx, w.wps.stream.Context())
|
||||
|
||||
wch := wp.cw.Watch(cctx, w.wr.key, opts...)
|
||||
wp.lg.Debug("watch", zap.String("key", w.wr.key))
|
||||
|
||||
for wr := range wch {
|
||||
wb.bcast(wr)
|
||||
update(wb)
|
||||
}
|
||||
}()
|
||||
return wb
|
||||
}
|
||||
|
||||
func (wb *watchBroadcast) bcast(wr clientv3.WatchResponse) {
|
||||
wb.mu.Lock()
|
||||
defer wb.mu.Unlock()
|
||||
// watchers start on the given revision, if any; ignore header rev on create
|
||||
if wb.responses > 0 || wb.nextrev == 0 {
|
||||
wb.nextrev = wr.Header.Revision + 1
|
||||
}
|
||||
wb.responses++
|
||||
for r := range wb.receivers {
|
||||
r.send(wr)
|
||||
}
|
||||
if len(wb.receivers) > 0 {
|
||||
eventsCoalescing.Add(float64(len(wb.receivers) - 1))
|
||||
}
|
||||
}
|
||||
|
||||
// add puts a watcher into receiving a broadcast if its revision at least
|
||||
// meets the broadcast revision. Returns true if added.
|
||||
func (wb *watchBroadcast) add(w *watcher) bool {
|
||||
wb.mu.Lock()
|
||||
defer wb.mu.Unlock()
|
||||
if wb.nextrev > w.nextrev || (wb.nextrev == 0 && w.nextrev != 0) {
|
||||
// wb is too far ahead, w will miss events
|
||||
// or wb is being established with a current watcher
|
||||
return false
|
||||
}
|
||||
if wb.responses == 0 {
|
||||
// Newly created; create event will be sent by etcd.
|
||||
wb.receivers[w] = struct{}{}
|
||||
return true
|
||||
}
|
||||
// already sent by etcd; emulate create event
|
||||
ok := w.post(&pb.WatchResponse{
|
||||
Header: &pb.ResponseHeader{
|
||||
// todo: fill in ClusterId
|
||||
// todo: fill in MemberId:
|
||||
Revision: w.nextrev,
|
||||
// todo: fill in RaftTerm:
|
||||
},
|
||||
WatchId: w.id,
|
||||
Created: true,
|
||||
})
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
wb.receivers[w] = struct{}{}
|
||||
watchersCoalescing.Inc()
|
||||
|
||||
return true
|
||||
}
|
||||
func (wb *watchBroadcast) delete(w *watcher) {
|
||||
wb.mu.Lock()
|
||||
defer wb.mu.Unlock()
|
||||
if _, ok := wb.receivers[w]; !ok {
|
||||
panic("deleting missing watcher from broadcast")
|
||||
}
|
||||
delete(wb.receivers, w)
|
||||
if len(wb.receivers) > 0 {
|
||||
// do not dec the only left watcher for coalescing.
|
||||
watchersCoalescing.Dec()
|
||||
}
|
||||
}
|
||||
|
||||
func (wb *watchBroadcast) size() int {
|
||||
wb.mu.RLock()
|
||||
defer wb.mu.RUnlock()
|
||||
return len(wb.receivers)
|
||||
}
|
||||
|
||||
func (wb *watchBroadcast) empty() bool { return wb.size() == 0 }
|
||||
|
||||
func (wb *watchBroadcast) stop() {
|
||||
if !wb.empty() {
|
||||
// do not dec the only left watcher for coalescing.
|
||||
watchersCoalescing.Sub(float64(wb.size() - 1))
|
||||
}
|
||||
|
||||
wb.cancel()
|
||||
|
||||
select {
|
||||
case <-wb.donec:
|
||||
// watchProxyStream will hold watchRanges global mutex lock all the time if client failed to cancel etcd watchers.
|
||||
// and it will cause the watch proxy to not work.
|
||||
// please see pr https://github.com/etcd-io/etcd/pull/12030 to get more detail info.
|
||||
case <-time.After(time.Second):
|
||||
wb.lg.Error("failed to cancel etcd watcher")
|
||||
}
|
||||
}
|
135
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watch_broadcasts.go
generated
vendored
135
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watch_broadcasts.go
generated
vendored
@ -1,135 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type watchBroadcasts struct {
|
||||
wp *watchProxy
|
||||
|
||||
// mu protects bcasts and watchers from the coalesce loop.
|
||||
mu sync.Mutex
|
||||
bcasts map[*watchBroadcast]struct{}
|
||||
watchers map[*watcher]*watchBroadcast
|
||||
|
||||
updatec chan *watchBroadcast
|
||||
donec chan struct{}
|
||||
}
|
||||
|
||||
// maxCoalesceRecievers prevents a popular watchBroadcast from being coalseced.
|
||||
const maxCoalesceReceivers = 5
|
||||
|
||||
func newWatchBroadcasts(wp *watchProxy) *watchBroadcasts {
|
||||
wbs := &watchBroadcasts{
|
||||
wp: wp,
|
||||
bcasts: make(map[*watchBroadcast]struct{}),
|
||||
watchers: make(map[*watcher]*watchBroadcast),
|
||||
updatec: make(chan *watchBroadcast, 1),
|
||||
donec: make(chan struct{}),
|
||||
}
|
||||
go func() {
|
||||
defer close(wbs.donec)
|
||||
for wb := range wbs.updatec {
|
||||
wbs.coalesce(wb)
|
||||
}
|
||||
}()
|
||||
return wbs
|
||||
}
|
||||
|
||||
func (wbs *watchBroadcasts) coalesce(wb *watchBroadcast) {
|
||||
if wb.size() >= maxCoalesceReceivers {
|
||||
return
|
||||
}
|
||||
wbs.mu.Lock()
|
||||
for wbswb := range wbs.bcasts {
|
||||
if wbswb == wb {
|
||||
continue
|
||||
}
|
||||
wb.mu.Lock()
|
||||
wbswb.mu.Lock()
|
||||
// 1. check if wbswb is behind wb so it won't skip any events in wb
|
||||
// 2. ensure wbswb started; nextrev == 0 may mean wbswb is waiting
|
||||
// for a current watcher and expects a create event from the server.
|
||||
if wb.nextrev >= wbswb.nextrev && wbswb.responses > 0 {
|
||||
for w := range wb.receivers {
|
||||
wbswb.receivers[w] = struct{}{}
|
||||
wbs.watchers[w] = wbswb
|
||||
}
|
||||
wb.receivers = nil
|
||||
}
|
||||
wbswb.mu.Unlock()
|
||||
wb.mu.Unlock()
|
||||
if wb.empty() {
|
||||
delete(wbs.bcasts, wb)
|
||||
wb.stop()
|
||||
break
|
||||
}
|
||||
}
|
||||
wbs.mu.Unlock()
|
||||
}
|
||||
|
||||
func (wbs *watchBroadcasts) add(w *watcher) {
|
||||
wbs.mu.Lock()
|
||||
defer wbs.mu.Unlock()
|
||||
// find fitting bcast
|
||||
for wb := range wbs.bcasts {
|
||||
if wb.add(w) {
|
||||
wbs.watchers[w] = wb
|
||||
return
|
||||
}
|
||||
}
|
||||
// no fit; create a bcast
|
||||
wb := newWatchBroadcast(wbs.wp.lg, wbs.wp, w, wbs.update)
|
||||
wbs.watchers[w] = wb
|
||||
wbs.bcasts[wb] = struct{}{}
|
||||
}
|
||||
|
||||
// delete removes a watcher and returns the number of remaining watchers.
|
||||
func (wbs *watchBroadcasts) delete(w *watcher) int {
|
||||
wbs.mu.Lock()
|
||||
defer wbs.mu.Unlock()
|
||||
|
||||
wb, ok := wbs.watchers[w]
|
||||
if !ok {
|
||||
panic("deleting missing watcher from broadcasts")
|
||||
}
|
||||
delete(wbs.watchers, w)
|
||||
wb.delete(w)
|
||||
if wb.empty() {
|
||||
delete(wbs.bcasts, wb)
|
||||
wb.stop()
|
||||
}
|
||||
return len(wbs.bcasts)
|
||||
}
|
||||
|
||||
func (wbs *watchBroadcasts) stop() {
|
||||
wbs.mu.Lock()
|
||||
for wb := range wbs.bcasts {
|
||||
wb.stop()
|
||||
}
|
||||
wbs.bcasts = nil
|
||||
close(wbs.updatec)
|
||||
wbs.mu.Unlock()
|
||||
<-wbs.donec
|
||||
}
|
||||
|
||||
func (wbs *watchBroadcasts) update(wb *watchBroadcast) {
|
||||
select {
|
||||
case wbs.updatec <- wb:
|
||||
default:
|
||||
}
|
||||
}
|
69
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watch_ranges.go
generated
vendored
69
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watch_ranges.go
generated
vendored
@ -1,69 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// watchRanges tracks all open watches for the proxy.
|
||||
type watchRanges struct {
|
||||
wp *watchProxy
|
||||
|
||||
mu sync.Mutex
|
||||
bcasts map[watchRange]*watchBroadcasts
|
||||
}
|
||||
|
||||
func newWatchRanges(wp *watchProxy) *watchRanges {
|
||||
return &watchRanges{
|
||||
wp: wp,
|
||||
bcasts: make(map[watchRange]*watchBroadcasts),
|
||||
}
|
||||
}
|
||||
|
||||
func (wrs *watchRanges) add(w *watcher) {
|
||||
wrs.mu.Lock()
|
||||
defer wrs.mu.Unlock()
|
||||
|
||||
if wbs := wrs.bcasts[w.wr]; wbs != nil {
|
||||
wbs.add(w)
|
||||
return
|
||||
}
|
||||
wbs := newWatchBroadcasts(wrs.wp)
|
||||
wrs.bcasts[w.wr] = wbs
|
||||
wbs.add(w)
|
||||
}
|
||||
|
||||
func (wrs *watchRanges) delete(w *watcher) {
|
||||
wrs.mu.Lock()
|
||||
defer wrs.mu.Unlock()
|
||||
wbs, ok := wrs.bcasts[w.wr]
|
||||
if !ok {
|
||||
panic("deleting missing range")
|
||||
}
|
||||
if wbs.delete(w) == 0 {
|
||||
wbs.stop()
|
||||
delete(wrs.bcasts, w.wr)
|
||||
}
|
||||
}
|
||||
|
||||
func (wrs *watchRanges) stop() {
|
||||
wrs.mu.Lock()
|
||||
defer wrs.mu.Unlock()
|
||||
for _, wb := range wrs.bcasts {
|
||||
wb.stop()
|
||||
}
|
||||
wrs.bcasts = nil
|
||||
}
|
130
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watcher.go
generated
vendored
130
vendor/go.etcd.io/etcd/server/v3/proxy/grpcproxy/watcher.go
generated
vendored
@ -1,130 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package grpcproxy
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/api/v3/mvccpb"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/mvcc"
|
||||
)
|
||||
|
||||
type watchRange struct {
|
||||
key, end string
|
||||
}
|
||||
|
||||
func (wr *watchRange) valid() bool {
|
||||
return len(wr.end) == 0 || wr.end > wr.key || (wr.end[0] == 0 && len(wr.end) == 1)
|
||||
}
|
||||
|
||||
type watcher struct {
|
||||
// user configuration
|
||||
|
||||
wr watchRange
|
||||
filters []mvcc.FilterFunc
|
||||
progress bool
|
||||
prevKV bool
|
||||
|
||||
// id is the id returned to the client on its watch stream.
|
||||
id int64
|
||||
// nextrev is the minimum expected next event revision.
|
||||
nextrev int64
|
||||
// lastHeader has the last header sent over the stream.
|
||||
lastHeader pb.ResponseHeader
|
||||
|
||||
// wps is the parent.
|
||||
wps *watchProxyStream
|
||||
}
|
||||
|
||||
// send filters out repeated events by discarding revisions older
|
||||
// than the last one sent over the watch channel.
|
||||
func (w *watcher) send(wr clientv3.WatchResponse) {
|
||||
if wr.IsProgressNotify() && !w.progress {
|
||||
return
|
||||
}
|
||||
if w.nextrev > wr.Header.Revision && len(wr.Events) > 0 {
|
||||
return
|
||||
}
|
||||
if w.nextrev == 0 {
|
||||
// current watch; expect updates following this revision
|
||||
w.nextrev = wr.Header.Revision + 1
|
||||
}
|
||||
|
||||
events := make([]*mvccpb.Event, 0, len(wr.Events))
|
||||
|
||||
var lastRev int64
|
||||
for i := range wr.Events {
|
||||
ev := (*mvccpb.Event)(wr.Events[i])
|
||||
if ev.Kv.ModRevision < w.nextrev {
|
||||
continue
|
||||
} else {
|
||||
// We cannot update w.rev here.
|
||||
// txn can have multiple events with the same rev.
|
||||
// If w.nextrev updates here, it would skip events in the same txn.
|
||||
lastRev = ev.Kv.ModRevision
|
||||
}
|
||||
|
||||
filtered := false
|
||||
for _, filter := range w.filters {
|
||||
if filter(*ev) {
|
||||
filtered = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if filtered {
|
||||
continue
|
||||
}
|
||||
|
||||
if !w.prevKV {
|
||||
evCopy := *ev
|
||||
evCopy.PrevKv = nil
|
||||
ev = &evCopy
|
||||
}
|
||||
events = append(events, ev)
|
||||
}
|
||||
|
||||
if lastRev >= w.nextrev {
|
||||
w.nextrev = lastRev + 1
|
||||
}
|
||||
|
||||
// all events are filtered out?
|
||||
if !wr.IsProgressNotify() && !wr.Created && len(events) == 0 && wr.CompactRevision == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
w.lastHeader = wr.Header
|
||||
w.post(&pb.WatchResponse{
|
||||
Header: &wr.Header,
|
||||
Created: wr.Created,
|
||||
CompactRevision: wr.CompactRevision,
|
||||
Canceled: wr.Canceled,
|
||||
WatchId: w.id,
|
||||
Events: events,
|
||||
})
|
||||
}
|
||||
|
||||
// post puts a watch response on the watcher's proxy stream channel
|
||||
func (w *watcher) post(wr *pb.WatchResponse) bool {
|
||||
select {
|
||||
case w.wps.watchCh <- wr:
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
w.wps.cancel()
|
||||
w.wps.lg.Error("failed to put a watch response on the watcher's proxy stream channel,err is timeout")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
202
vendor/go.etcd.io/etcd/tests/v3/LICENSE
generated
vendored
202
vendor/go.etcd.io/etcd/tests/v3/LICENSE
generated
vendored
@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
228
vendor/go.etcd.io/etcd/tests/v3/integration/bridge.go
generated
vendored
228
vendor/go.etcd.io/etcd/tests/v3/integration/bridge.go
generated
vendored
@ -1,228 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"go.etcd.io/etcd/client/pkg/v3/transport"
|
||||
)
|
||||
|
||||
// bridge creates a unix socket bridge to another unix socket, making it possible
|
||||
// to disconnect grpc network connections without closing the logical grpc connection.
|
||||
type bridge struct {
|
||||
inaddr string
|
||||
outaddr string
|
||||
l net.Listener
|
||||
conns map[*bridgeConn]struct{}
|
||||
|
||||
stopc chan struct{}
|
||||
pausec chan struct{}
|
||||
blackholec chan struct{}
|
||||
wg sync.WaitGroup
|
||||
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func newBridge(addr string) (*bridge, error) {
|
||||
b := &bridge{
|
||||
// bridge "port" is ("%05d%05d0", port, pid) since go1.8 expects the port to be a number
|
||||
inaddr: addr + "0",
|
||||
outaddr: addr,
|
||||
conns: make(map[*bridgeConn]struct{}),
|
||||
stopc: make(chan struct{}),
|
||||
pausec: make(chan struct{}),
|
||||
blackholec: make(chan struct{}),
|
||||
}
|
||||
close(b.pausec)
|
||||
|
||||
l, err := transport.NewUnixListener(b.inaddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listen failed on socket %s (%v)", addr, err)
|
||||
}
|
||||
b.l = l
|
||||
b.wg.Add(1)
|
||||
go b.serveListen()
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *bridge) URL() string { return "unix://" + b.inaddr }
|
||||
|
||||
func (b *bridge) Close() {
|
||||
b.l.Close()
|
||||
b.mu.Lock()
|
||||
select {
|
||||
case <-b.stopc:
|
||||
default:
|
||||
close(b.stopc)
|
||||
}
|
||||
b.mu.Unlock()
|
||||
b.wg.Wait()
|
||||
}
|
||||
|
||||
func (b *bridge) Reset() {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
for bc := range b.conns {
|
||||
bc.Close()
|
||||
}
|
||||
b.conns = make(map[*bridgeConn]struct{})
|
||||
}
|
||||
|
||||
func (b *bridge) Pause() {
|
||||
b.mu.Lock()
|
||||
b.pausec = make(chan struct{})
|
||||
b.mu.Unlock()
|
||||
}
|
||||
|
||||
func (b *bridge) Unpause() {
|
||||
b.mu.Lock()
|
||||
select {
|
||||
case <-b.pausec:
|
||||
default:
|
||||
close(b.pausec)
|
||||
}
|
||||
b.mu.Unlock()
|
||||
}
|
||||
|
||||
func (b *bridge) serveListen() {
|
||||
defer func() {
|
||||
b.l.Close()
|
||||
b.mu.Lock()
|
||||
for bc := range b.conns {
|
||||
bc.Close()
|
||||
}
|
||||
b.mu.Unlock()
|
||||
b.wg.Done()
|
||||
}()
|
||||
|
||||
for {
|
||||
inc, ierr := b.l.Accept()
|
||||
if ierr != nil {
|
||||
return
|
||||
}
|
||||
b.mu.Lock()
|
||||
pausec := b.pausec
|
||||
b.mu.Unlock()
|
||||
select {
|
||||
case <-b.stopc:
|
||||
inc.Close()
|
||||
return
|
||||
case <-pausec:
|
||||
}
|
||||
|
||||
outc, oerr := net.Dial("unix", b.outaddr)
|
||||
if oerr != nil {
|
||||
inc.Close()
|
||||
return
|
||||
}
|
||||
|
||||
bc := &bridgeConn{inc, outc, make(chan struct{})}
|
||||
b.wg.Add(1)
|
||||
b.mu.Lock()
|
||||
b.conns[bc] = struct{}{}
|
||||
go b.serveConn(bc)
|
||||
b.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *bridge) serveConn(bc *bridgeConn) {
|
||||
defer func() {
|
||||
close(bc.donec)
|
||||
bc.Close()
|
||||
b.mu.Lock()
|
||||
delete(b.conns, bc)
|
||||
b.mu.Unlock()
|
||||
b.wg.Done()
|
||||
}()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
b.ioCopy(bc.out, bc.in)
|
||||
bc.close()
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
b.ioCopy(bc.in, bc.out)
|
||||
bc.close()
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
type bridgeConn struct {
|
||||
in net.Conn
|
||||
out net.Conn
|
||||
donec chan struct{}
|
||||
}
|
||||
|
||||
func (bc *bridgeConn) Close() {
|
||||
bc.close()
|
||||
<-bc.donec
|
||||
}
|
||||
|
||||
func (bc *bridgeConn) close() {
|
||||
bc.in.Close()
|
||||
bc.out.Close()
|
||||
}
|
||||
|
||||
func (b *bridge) Blackhole() {
|
||||
b.mu.Lock()
|
||||
close(b.blackholec)
|
||||
b.mu.Unlock()
|
||||
}
|
||||
|
||||
func (b *bridge) Unblackhole() {
|
||||
b.mu.Lock()
|
||||
for bc := range b.conns {
|
||||
bc.Close()
|
||||
}
|
||||
b.conns = make(map[*bridgeConn]struct{})
|
||||
b.blackholec = make(chan struct{})
|
||||
b.mu.Unlock()
|
||||
}
|
||||
|
||||
// ref. https://github.com/golang/go/blob/master/src/io/io.go copyBuffer
|
||||
func (b *bridge) ioCopy(dst io.Writer, src io.Reader) (err error) {
|
||||
buf := make([]byte, 32*1024)
|
||||
for {
|
||||
select {
|
||||
case <-b.blackholec:
|
||||
io.Copy(ioutil.Discard, src)
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
nr, er := src.Read(buf)
|
||||
if nr > 0 {
|
||||
nw, ew := dst.Write(buf[0:nr])
|
||||
if ew != nil {
|
||||
return ew
|
||||
}
|
||||
if nr != nw {
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
}
|
||||
if er != nil {
|
||||
err = er
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
1533
vendor/go.etcd.io/etcd/tests/v3/integration/cluster.go
generated
vendored
1533
vendor/go.etcd.io/etcd/tests/v3/integration/cluster.go
generated
vendored
File diff suppressed because it is too large
Load Diff
46
vendor/go.etcd.io/etcd/tests/v3/integration/cluster_direct.go
generated
vendored
46
vendor/go.etcd.io/etcd/tests/v3/integration/cluster_direct.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !cluster_proxy
|
||||
// +build !cluster_proxy
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/v3election/v3electionpb"
|
||||
"go.etcd.io/etcd/server/v3/etcdserver/api/v3lock/v3lockpb"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const ThroughProxy = false
|
||||
|
||||
func toGRPC(c *clientv3.Client) grpcAPI {
|
||||
return grpcAPI{
|
||||
pb.NewClusterClient(c.ActiveConnection()),
|
||||
pb.NewKVClient(c.ActiveConnection()),
|
||||
pb.NewLeaseClient(c.ActiveConnection()),
|
||||
pb.NewWatchClient(c.ActiveConnection()),
|
||||
pb.NewMaintenanceClient(c.ActiveConnection()),
|
||||
pb.NewAuthClient(c.ActiveConnection()),
|
||||
v3lockpb.NewLockClient(c.ActiveConnection()),
|
||||
v3electionpb.NewElectionClient(c.ActiveConnection()),
|
||||
}
|
||||
}
|
||||
|
||||
func newClientV3(cfg clientv3.Config, lg *zap.Logger) (*clientv3.Client, error) {
|
||||
cfg.Logger = lg
|
||||
return clientv3.New(cfg)
|
||||
}
|
132
vendor/go.etcd.io/etcd/tests/v3/integration/cluster_proxy.go
generated
vendored
132
vendor/go.etcd.io/etcd/tests/v3/integration/cluster_proxy.go
generated
vendored
@ -1,132 +0,0 @@
|
||||
// Copyright 2016 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build cluster_proxy
|
||||
// +build cluster_proxy
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/client/v3/namespace"
|
||||
"go.etcd.io/etcd/server/v3/proxy/grpcproxy"
|
||||
"go.etcd.io/etcd/server/v3/proxy/grpcproxy/adapter"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const ThroughProxy = true
|
||||
|
||||
var (
|
||||
pmu sync.Mutex
|
||||
proxies map[*clientv3.Client]grpcClientProxy = make(map[*clientv3.Client]grpcClientProxy)
|
||||
)
|
||||
|
||||
const proxyNamespace = "proxy-namespace"
|
||||
|
||||
type grpcClientProxy struct {
|
||||
ctx context.Context
|
||||
ctxCancel func()
|
||||
grpc grpcAPI
|
||||
wdonec <-chan struct{}
|
||||
kvdonec <-chan struct{}
|
||||
lpdonec <-chan struct{}
|
||||
}
|
||||
|
||||
func toGRPC(c *clientv3.Client) grpcAPI {
|
||||
pmu.Lock()
|
||||
defer pmu.Unlock()
|
||||
|
||||
// dedicated context bound to 'grpc-proxy' lifetype
|
||||
// (so in practice lifetime of the client connection to the proxy).
|
||||
// TODO: Refactor to a separate clientv3.Client instance instead of the context alone.
|
||||
ctx, ctxCancel := context.WithCancel(context.WithValue(context.TODO(), "_name", "grpcProxyContext"))
|
||||
|
||||
lg := c.GetLogger()
|
||||
|
||||
if v, ok := proxies[c]; ok {
|
||||
return v.grpc
|
||||
}
|
||||
|
||||
// test namespacing proxy
|
||||
c.KV = namespace.NewKV(c.KV, proxyNamespace)
|
||||
c.Watcher = namespace.NewWatcher(c.Watcher, proxyNamespace)
|
||||
c.Lease = namespace.NewLease(c.Lease, proxyNamespace)
|
||||
// test coalescing/caching proxy
|
||||
kvp, kvpch := grpcproxy.NewKvProxy(c)
|
||||
wp, wpch := grpcproxy.NewWatchProxy(ctx, lg, c)
|
||||
lp, lpch := grpcproxy.NewLeaseProxy(ctx, c)
|
||||
mp := grpcproxy.NewMaintenanceProxy(c)
|
||||
clp, _ := grpcproxy.NewClusterProxy(lg, c, "", "") // without registering proxy URLs
|
||||
authp := grpcproxy.NewAuthProxy(c)
|
||||
lockp := grpcproxy.NewLockProxy(c)
|
||||
electp := grpcproxy.NewElectionProxy(c)
|
||||
|
||||
grpc := grpcAPI{
|
||||
adapter.ClusterServerToClusterClient(clp),
|
||||
adapter.KvServerToKvClient(kvp),
|
||||
adapter.LeaseServerToLeaseClient(lp),
|
||||
adapter.WatchServerToWatchClient(wp),
|
||||
adapter.MaintenanceServerToMaintenanceClient(mp),
|
||||
adapter.AuthServerToAuthClient(authp),
|
||||
adapter.LockServerToLockClient(lockp),
|
||||
adapter.ElectionServerToElectionClient(electp),
|
||||
}
|
||||
proxies[c] = grpcClientProxy{ctx: ctx, ctxCancel: ctxCancel, grpc: grpc, wdonec: wpch, kvdonec: kvpch, lpdonec: lpch}
|
||||
return grpc
|
||||
}
|
||||
|
||||
type proxyCloser struct {
|
||||
clientv3.Watcher
|
||||
proxyCtxCancel func()
|
||||
wdonec <-chan struct{}
|
||||
kvdonec <-chan struct{}
|
||||
lclose func()
|
||||
lpdonec <-chan struct{}
|
||||
}
|
||||
|
||||
func (pc *proxyCloser) Close() error {
|
||||
pc.proxyCtxCancel()
|
||||
<-pc.kvdonec
|
||||
err := pc.Watcher.Close()
|
||||
<-pc.wdonec
|
||||
pc.lclose()
|
||||
<-pc.lpdonec
|
||||
return err
|
||||
}
|
||||
|
||||
func newClientV3(cfg clientv3.Config, lg *zap.Logger) (*clientv3.Client, error) {
|
||||
cfg.Logger = lg
|
||||
c, err := clientv3.New(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rpc := toGRPC(c)
|
||||
c.KV = clientv3.NewKVFromKVClient(rpc.KV, c)
|
||||
pmu.Lock()
|
||||
lc := c.Lease
|
||||
c.Lease = clientv3.NewLeaseFromLeaseClient(rpc.Lease, c, cfg.DialTimeout)
|
||||
c.Watcher = &proxyCloser{
|
||||
Watcher: clientv3.NewWatchFromWatchClient(rpc.Watch, c),
|
||||
wdonec: proxies[c].wdonec,
|
||||
kvdonec: proxies[c].kvdonec,
|
||||
lclose: func() { lc.Close() },
|
||||
lpdonec: proxies[c].lpdonec,
|
||||
proxyCtxCancel: proxies[c].ctxCancel,
|
||||
}
|
||||
pmu.Unlock()
|
||||
return c, nil
|
||||
}
|
25
vendor/go.etcd.io/etcd/tests/v3/integration/doc.go
generated
vendored
25
vendor/go.etcd.io/etcd/tests/v3/integration/doc.go
generated
vendored
@ -1,25 +0,0 @@
|
||||
// Copyright 2015 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
Package integration implements tests built upon embedded etcd, and focus on
|
||||
etcd correctness.
|
||||
|
||||
Features/goals of the integration tests:
|
||||
1. test the whole code base except command-line parsing.
|
||||
2. check internal data, including raft, store and etc.
|
||||
3. based on goroutines, which is faster than process.
|
||||
4. mainly tests user behavior and user-facing API.
|
||||
*/
|
||||
package integration
|
120
vendor/go.etcd.io/etcd/tests/v3/integration/lazy_cluster.go
generated
vendored
120
vendor/go.etcd.io/etcd/tests/v3/integration/lazy_cluster.go
generated
vendored
@ -1,120 +0,0 @@
|
||||
// Copyright 2020 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.etcd.io/etcd/client/pkg/v3/testutil"
|
||||
"go.etcd.io/etcd/client/pkg/v3/transport"
|
||||
)
|
||||
|
||||
// Infrastructure to provision a single shared cluster for tests - only
|
||||
// when its needed.
|
||||
//
|
||||
// See ./tests/integration/clientv3/examples/main_test.go for canonical usage.
|
||||
// Please notice that the shared (LazyCluster's) state is preserved between
|
||||
// testcases, so left-over state might has cross-testcase effects.
|
||||
// Prefer dedicated clusters for substancial test-cases.
|
||||
|
||||
type LazyCluster interface {
|
||||
// EndpointsV2 - exposes connection points for client v2.
|
||||
// Calls to this method might initialize the cluster.
|
||||
EndpointsV2() []string
|
||||
|
||||
// EndpointsV3 - exposes connection points for client v3.
|
||||
// Calls to this method might initialize the cluster.
|
||||
EndpointsV3() []string
|
||||
|
||||
// Cluster - calls to this method might initialize the cluster.
|
||||
Cluster() *ClusterV3
|
||||
|
||||
// Transport - call to this method might initialize the cluster.
|
||||
Transport() *http.Transport
|
||||
|
||||
Terminate()
|
||||
|
||||
TB() testutil.TB
|
||||
}
|
||||
|
||||
type lazyCluster struct {
|
||||
cfg ClusterConfig
|
||||
cluster *ClusterV3
|
||||
transport *http.Transport
|
||||
once sync.Once
|
||||
tb testutil.TB
|
||||
closer func()
|
||||
}
|
||||
|
||||
// NewLazyCluster returns a new test cluster handler that gets created on the
|
||||
// first call to GetEndpoints() or GetTransport()
|
||||
func NewLazyCluster() LazyCluster {
|
||||
return NewLazyClusterWithConfig(ClusterConfig{Size: 1})
|
||||
}
|
||||
|
||||
// NewLazyClusterWithConfig returns a new test cluster handler that gets created
|
||||
// on the first call to GetEndpoints() or GetTransport()
|
||||
func NewLazyClusterWithConfig(cfg ClusterConfig) LazyCluster {
|
||||
tb, closer := testutil.NewTestingTBProthesis("lazy_cluster")
|
||||
return &lazyCluster{cfg: cfg, tb: tb, closer: closer}
|
||||
}
|
||||
|
||||
func (lc *lazyCluster) mustLazyInit() {
|
||||
lc.once.Do(func() {
|
||||
var err error
|
||||
lc.transport, err = transport.NewTransport(transport.TLSInfo{}, time.Second)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
lc.cluster = NewClusterV3(lc.tb, &lc.cfg)
|
||||
})
|
||||
}
|
||||
|
||||
func (lc *lazyCluster) Terminate() {
|
||||
lc.tb.Logf("Terminating...")
|
||||
if lc != nil && lc.cluster != nil {
|
||||
lc.cluster.Terminate(nil)
|
||||
lc.cluster = nil
|
||||
}
|
||||
if lc.closer != nil {
|
||||
lc.tb.Logf("Closer...")
|
||||
lc.closer()
|
||||
}
|
||||
}
|
||||
|
||||
func (lc *lazyCluster) EndpointsV2() []string {
|
||||
return []string{lc.Cluster().Members[0].URL()}
|
||||
}
|
||||
|
||||
func (lc *lazyCluster) EndpointsV3() []string {
|
||||
return lc.Cluster().Client(0).Endpoints()
|
||||
}
|
||||
|
||||
func (lc *lazyCluster) Cluster() *ClusterV3 {
|
||||
lc.mustLazyInit()
|
||||
return lc.cluster
|
||||
}
|
||||
|
||||
func (lc *lazyCluster) Transport() *http.Transport {
|
||||
lc.mustLazyInit()
|
||||
return lc.transport
|
||||
}
|
||||
|
||||
func (lc *lazyCluster) TB() testutil.TB {
|
||||
return lc.tb
|
||||
}
|
136
vendor/go.etcd.io/etcd/tests/v3/integration/testing.go
generated
vendored
136
vendor/go.etcd.io/etcd/tests/v3/integration/testing.go
generated
vendored
@ -1,136 +0,0 @@
|
||||
// Copyright 2021 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
grpc_logsettable "github.com/grpc-ecosystem/go-grpc-middleware/logging/settable"
|
||||
"go.etcd.io/etcd/client/pkg/v3/testutil"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"go.etcd.io/etcd/server/v3/embed"
|
||||
"go.etcd.io/etcd/server/v3/verify"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"go.uber.org/zap/zapgrpc"
|
||||
"go.uber.org/zap/zaptest"
|
||||
)
|
||||
|
||||
var grpc_logger grpc_logsettable.SettableLoggerV2
|
||||
var insideTestContext bool
|
||||
|
||||
func init() {
|
||||
grpc_logger = grpc_logsettable.ReplaceGrpcLoggerV2()
|
||||
}
|
||||
|
||||
type testOptions struct {
|
||||
goLeakDetection bool
|
||||
skipInShort bool
|
||||
}
|
||||
|
||||
func newTestOptions(opts ...TestOption) *testOptions {
|
||||
o := &testOptions{goLeakDetection: true, skipInShort: true}
|
||||
for _, opt := range opts {
|
||||
opt(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
type TestOption func(opt *testOptions)
|
||||
|
||||
// WithoutGoLeakDetection disables checking whether a testcase leaked a goroutine.
|
||||
func WithoutGoLeakDetection() TestOption {
|
||||
return func(opt *testOptions) { opt.goLeakDetection = false }
|
||||
}
|
||||
|
||||
func WithoutSkipInShort() TestOption {
|
||||
return func(opt *testOptions) { opt.skipInShort = false }
|
||||
}
|
||||
|
||||
// BeforeTestExternal initializes test context and is targeted for external APIs.
|
||||
// In general the `integration` package is not targeted to be used outside of
|
||||
// etcd project, but till the dedicated package is developed, this is
|
||||
// the best entry point so far (without backward compatibility promise).
|
||||
func BeforeTestExternal(t testutil.TB) {
|
||||
BeforeTest(t, WithoutSkipInShort(), WithoutGoLeakDetection())
|
||||
}
|
||||
|
||||
func BeforeTest(t testutil.TB, opts ...TestOption) {
|
||||
t.Helper()
|
||||
options := newTestOptions(opts...)
|
||||
|
||||
if options.skipInShort {
|
||||
testutil.SkipTestIfShortMode(t, "Cannot create clusters in --short tests")
|
||||
}
|
||||
|
||||
if options.goLeakDetection {
|
||||
testutil.RegisterLeakDetection(t)
|
||||
}
|
||||
|
||||
previousWD, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
previousInsideTestContext := insideTestContext
|
||||
|
||||
// Registering cleanup early, such it will get executed even if the helper fails.
|
||||
t.Cleanup(func() {
|
||||
grpc_logger.Reset()
|
||||
insideTestContext = previousInsideTestContext
|
||||
os.Chdir(previousWD)
|
||||
})
|
||||
|
||||
if insideTestContext {
|
||||
t.Fatal("already in test context. BeforeTest was likely already called")
|
||||
}
|
||||
|
||||
grpc_logger.Set(zapgrpc.NewLogger(zaptest.NewLogger(t).Named("grpc")))
|
||||
insideTestContext = true
|
||||
|
||||
// Integration tests should verify written state as much as possible.
|
||||
os.Setenv(verify.ENV_VERIFY, verify.ENV_VERIFY_ALL_VALUE)
|
||||
os.Chdir(t.TempDir())
|
||||
}
|
||||
|
||||
func assertInTestContext(t testutil.TB) {
|
||||
if !insideTestContext {
|
||||
t.Errorf("the function can be called only in the test context. Was integration.BeforeTest() called ?")
|
||||
}
|
||||
}
|
||||
|
||||
func MustAbsPath(path string) string {
|
||||
abs, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return abs
|
||||
}
|
||||
|
||||
func NewEmbedConfig(t testing.TB, name string) *embed.Config {
|
||||
cfg := embed.NewConfig()
|
||||
cfg.Name = name
|
||||
lg := zaptest.NewLogger(t, zaptest.Level(zapcore.InfoLevel)).Named(cfg.Name)
|
||||
cfg.ZapLoggerBuilder = embed.NewZapLoggerBuilder(lg)
|
||||
cfg.Dir = t.TempDir()
|
||||
return cfg
|
||||
}
|
||||
|
||||
func NewClient(t testing.TB, cfg clientv3.Config) (*clientv3.Client, error) {
|
||||
if cfg.Logger != nil {
|
||||
cfg.Logger = zaptest.NewLogger(t)
|
||||
}
|
||||
return clientv3.New(cfg)
|
||||
}
|
17
vendor/modules.txt
vendored
17
vendor/modules.txt
vendored
@ -467,7 +467,6 @@ github.com/gregjones/httpcache
|
||||
github.com/gregjones/httpcache/diskcache
|
||||
# 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-middleware
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/logging/settable
|
||||
# github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 => github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus
|
||||
# github.com/grpc-ecosystem/grpc-gateway v1.16.0 => github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||
@ -798,7 +797,6 @@ go.etcd.io/etcd/client/pkg/v3/logutil
|
||||
go.etcd.io/etcd/client/pkg/v3/pathutil
|
||||
go.etcd.io/etcd/client/pkg/v3/srv
|
||||
go.etcd.io/etcd/client/pkg/v3/systemd
|
||||
go.etcd.io/etcd/client/pkg/v3/testutil
|
||||
go.etcd.io/etcd/client/pkg/v3/tlsutil
|
||||
go.etcd.io/etcd/client/pkg/v3/transport
|
||||
go.etcd.io/etcd/client/pkg/v3/types
|
||||
@ -811,9 +809,6 @@ go.etcd.io/etcd/client/v3/concurrency
|
||||
go.etcd.io/etcd/client/v3/credentials
|
||||
go.etcd.io/etcd/client/v3/internal/endpoint
|
||||
go.etcd.io/etcd/client/v3/internal/resolver
|
||||
go.etcd.io/etcd/client/v3/namespace
|
||||
go.etcd.io/etcd/client/v3/naming/endpoints
|
||||
go.etcd.io/etcd/client/v3/naming/endpoints/internal
|
||||
# go.etcd.io/etcd/pkg/v3 v3.5.0 => go.etcd.io/etcd/pkg/v3 v3.5.0
|
||||
go.etcd.io/etcd/pkg/v3/adt
|
||||
go.etcd.io/etcd/pkg/v3/contention
|
||||
@ -873,14 +868,10 @@ go.etcd.io/etcd/server/v3/lease/leasepb
|
||||
go.etcd.io/etcd/server/v3/mvcc
|
||||
go.etcd.io/etcd/server/v3/mvcc/backend
|
||||
go.etcd.io/etcd/server/v3/mvcc/buckets
|
||||
go.etcd.io/etcd/server/v3/proxy/grpcproxy
|
||||
go.etcd.io/etcd/server/v3/proxy/grpcproxy/adapter
|
||||
go.etcd.io/etcd/server/v3/proxy/grpcproxy/cache
|
||||
go.etcd.io/etcd/server/v3/verify
|
||||
go.etcd.io/etcd/server/v3/wal
|
||||
go.etcd.io/etcd/server/v3/wal/walpb
|
||||
# go.etcd.io/etcd/tests/v3 v3.5.0 => go.etcd.io/etcd/tests/v3 v3.5.0
|
||||
go.etcd.io/etcd/tests/v3/integration
|
||||
# go.opencensus.io v0.22.3 => go.opencensus.io v0.22.3
|
||||
go.opencensus.io
|
||||
go.opencensus.io/internal
|
||||
@ -1539,6 +1530,7 @@ k8s.io/apiserver/pkg/storage/errors
|
||||
k8s.io/apiserver/pkg/storage/etcd3
|
||||
k8s.io/apiserver/pkg/storage/etcd3/metrics
|
||||
k8s.io/apiserver/pkg/storage/etcd3/testing
|
||||
k8s.io/apiserver/pkg/storage/etcd3/testserver
|
||||
k8s.io/apiserver/pkg/storage/names
|
||||
k8s.io/apiserver/pkg/storage/storagebackend
|
||||
k8s.io/apiserver/pkg/storage/storagebackend/factory
|
||||
@ -2461,7 +2453,6 @@ sigs.k8s.io/yaml
|
||||
# github.com/emicklei/go-restful => github.com/emicklei/go-restful v2.9.5+incompatible
|
||||
# github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d
|
||||
# github.com/envoyproxy/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v0.1.0
|
||||
# github.com/etcd-io/gofail => github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca
|
||||
# github.com/euank/go-kmsg-parser => github.com/euank/go-kmsg-parser v2.0.0+incompatible
|
||||
# github.com/evanphx/json-patch => github.com/evanphx/json-patch v4.11.0+incompatible
|
||||
# github.com/exponent-io/jsonpath => github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d
|
||||
@ -2563,7 +2554,7 @@ sigs.k8s.io/yaml
|
||||
# github.com/mailru/easyjson => github.com/mailru/easyjson v0.7.6
|
||||
# github.com/mattn/go-colorable => github.com/mattn/go-colorable v0.0.9
|
||||
# github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.3
|
||||
# github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.9
|
||||
# github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.7
|
||||
# github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369
|
||||
# github.com/miekg/dns => github.com/miekg/dns v1.0.14
|
||||
# github.com/mindprince/gonvml => github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989
|
||||
@ -2591,7 +2582,7 @@ sigs.k8s.io/yaml
|
||||
# github.com/mxk/go-flowrate => github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
||||
# github.com/niemeyer/pretty => github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e
|
||||
# github.com/nxadm/tail => github.com/nxadm/tail v1.4.4
|
||||
# github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.5
|
||||
# github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.4
|
||||
# github.com/onsi/ginkgo => github.com/onsi/ginkgo v1.14.0
|
||||
# github.com/onsi/gomega => github.com/onsi/gomega v1.10.1
|
||||
# github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0
|
||||
@ -2655,11 +2646,9 @@ sigs.k8s.io/yaml
|
||||
# go.etcd.io/etcd/client/pkg/v3 => go.etcd.io/etcd/client/pkg/v3 v3.5.0
|
||||
# go.etcd.io/etcd/client/v2 => go.etcd.io/etcd/client/v2 v2.305.0
|
||||
# go.etcd.io/etcd/client/v3 => go.etcd.io/etcd/client/v3 v3.5.0
|
||||
# go.etcd.io/etcd/etcdutl/v3 => go.etcd.io/etcd/etcdutl/v3 v3.5.0
|
||||
# go.etcd.io/etcd/pkg/v3 => go.etcd.io/etcd/pkg/v3 v3.5.0
|
||||
# go.etcd.io/etcd/raft/v3 => go.etcd.io/etcd/raft/v3 v3.5.0
|
||||
# go.etcd.io/etcd/server/v3 => go.etcd.io/etcd/server/v3 v3.5.0
|
||||
# go.etcd.io/etcd/tests/v3 => go.etcd.io/etcd/tests/v3 v3.5.0
|
||||
# go.opencensus.io => go.opencensus.io v0.22.3
|
||||
# go.opentelemetry.io/contrib => go.opentelemetry.io/contrib v0.20.0
|
||||
# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0
|
||||
|
Loading…
Reference in New Issue
Block a user