mirror of
https://github.com/kubernetes/client-go.git
synced 2026-06-24 10:44:29 +00:00
Compare commits
118 Commits
kubernetes
...
kubernetes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5614af16d | ||
|
|
1a481fb1e3 | ||
|
|
0bdba2f918 | ||
|
|
f79cf5fbef | ||
|
|
af0e486466 | ||
|
|
6663414a1f | ||
|
|
ac8adc6f4c | ||
|
|
6c8f3ca2c6 | ||
|
|
464ec5ba04 | ||
|
|
d81654af9d | ||
|
|
d1b30110f1 | ||
|
|
14c42cd304 | ||
|
|
57ffd16d28 | ||
|
|
8a1fbdc8bb | ||
|
|
cc50c9b333 | ||
|
|
bd505ee787 | ||
|
|
dc265f33cf | ||
|
|
5462db5944 | ||
|
|
c51c673cf8 | ||
|
|
172b42569c | ||
|
|
e318746e79 | ||
|
|
6cdcb13531 | ||
|
|
9be50f2e07 | ||
|
|
1210218b4a | ||
|
|
c4ea3eed4f | ||
|
|
911ef75fbc | ||
|
|
c918cd02a1 | ||
|
|
24302e441b | ||
|
|
95b72f7306 | ||
|
|
b1fd789501 | ||
|
|
ec28f1ce46 | ||
|
|
a746c2f219 | ||
|
|
9c30dbec4d | ||
|
|
0ebb3d5f49 | ||
|
|
1289614f84 | ||
|
|
ad4f099992 | ||
|
|
3eb165927d | ||
|
|
95884bf844 | ||
|
|
1db9859ae8 | ||
|
|
07054768d9 | ||
|
|
6ff1103255 | ||
|
|
61aeaa97a2 | ||
|
|
0e97bf0202 | ||
|
|
bec79dc075 | ||
|
|
0df3af31cd | ||
|
|
18d8747a77 | ||
|
|
d147ce7d6e | ||
|
|
ab4e4fccf4 | ||
|
|
2bd34d193b | ||
|
|
bc70a20c12 | ||
|
|
bfc25e7605 | ||
|
|
bcb3724b2b | ||
|
|
a537b01432 | ||
|
|
6078bde84c | ||
|
|
297c8350f5 | ||
|
|
f8b3113764 | ||
|
|
ecd4f6fb8c | ||
|
|
67a52dfbe2 | ||
|
|
6f3bc4ba92 | ||
|
|
26b1e9b529 | ||
|
|
86c133ba28 | ||
|
|
e6a1dc4b13 | ||
|
|
aebe267284 | ||
|
|
e0bb139390 | ||
|
|
6d3b14b468 | ||
|
|
67a413f31a | ||
|
|
4fe1937613 | ||
|
|
9bcaef49c8 | ||
|
|
fc74d0f6b3 | ||
|
|
a7d8568b02 | ||
|
|
e990876d88 | ||
|
|
9781541482 | ||
|
|
0e80a77286 | ||
|
|
3fe2abece8 | ||
|
|
7f988d725c | ||
|
|
d4d906eb58 | ||
|
|
326ca7a019 | ||
|
|
cb7b787fa1 | ||
|
|
065c7aba1f | ||
|
|
325de63e79 | ||
|
|
8248d0a0e6 | ||
|
|
696c159e45 | ||
|
|
b4d94f0160 | ||
|
|
33ba610635 | ||
|
|
532b6f676e | ||
|
|
51b2905727 | ||
|
|
15739c3f80 | ||
|
|
6ddd067b15 | ||
|
|
541253da74 | ||
|
|
cc5a7c7149 | ||
|
|
597bab4578 | ||
|
|
9fc8bb16d6 | ||
|
|
5c0e283ed8 | ||
|
|
cdbd92c111 | ||
|
|
72094bc6d5 | ||
|
|
bac0f5a6c7 | ||
|
|
f4e58ce609 | ||
|
|
c8dc69f8a8 | ||
|
|
6a1fb71239 | ||
|
|
7ee6383729 | ||
|
|
33fd3701cd | ||
|
|
8355a02ca7 | ||
|
|
6de8fdd410 | ||
|
|
cca417f1ca | ||
|
|
e290f153d1 | ||
|
|
92cf7d1eaf | ||
|
|
1ca6f0db2b | ||
|
|
d522c037ae | ||
|
|
17815e944e | ||
|
|
7eecfc25a0 | ||
|
|
48bc0598fd | ||
|
|
689d090711 | ||
|
|
31cdc04542 | ||
|
|
8ade4cae05 | ||
|
|
cde59a28d7 | ||
|
|
ba49d2a180 | ||
|
|
1ff77877ed | ||
|
|
cdbf1c4b62 |
118
Godeps/Godeps.json
generated
118
Godeps/Godeps.json
generated
@@ -8,11 +8,35 @@
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "cloud.google.com/go",
|
||||
"Rev": "v0.34.0"
|
||||
"Rev": "v0.38.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest",
|
||||
"Rev": "v11.1.2"
|
||||
"ImportPath": "github.com/Azure/go-autorest/autorest",
|
||||
"Rev": "v0.9.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/autorest/adal",
|
||||
"Rev": "v0.5.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/autorest/date",
|
||||
"Rev": "v0.1.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/autorest/mocks",
|
||||
"Rev": "v0.2.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/logger",
|
||||
"Rev": "v0.1.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/tracing",
|
||||
"Rev": "v0.5.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/BurntSushi/toml",
|
||||
"Rev": "v0.3.1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/NYTimes/gziphandler",
|
||||
@@ -26,13 +50,17 @@
|
||||
"ImportPath": "github.com/PuerkitoBio/urlesc",
|
||||
"Rev": "5bd2802263f2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/client9/misspell",
|
||||
"Rev": "v0.3.4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew",
|
||||
"Rev": "v1.1.1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dgrijalva/jwt-go",
|
||||
"Rev": "01aeca54ebda"
|
||||
"Rev": "v3.2.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/spdystream",
|
||||
@@ -58,6 +86,10 @@
|
||||
"ImportPath": "github.com/ghodss/yaml",
|
||||
"Rev": "73d445a93680"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-logr/logr",
|
||||
"Rev": "v0.1.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/jsonpointer",
|
||||
"Rev": "46af16f9f7b1"
|
||||
@@ -78,17 +110,25 @@
|
||||
"ImportPath": "github.com/gogo/protobuf",
|
||||
"Rev": "65acae22fc9d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/glog",
|
||||
"Rev": "23def4e6c14b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/groupcache",
|
||||
"Rev": "02826c3e7903"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf",
|
||||
"ImportPath": "github.com/golang/mock",
|
||||
"Rev": "v1.2.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf",
|
||||
"Rev": "v1.3.2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/btree",
|
||||
"Rev": "7d79101e329e"
|
||||
"Rev": "v1.0.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/go-cmp",
|
||||
@@ -98,10 +138,22 @@
|
||||
"ImportPath": "github.com/google/gofuzz",
|
||||
"Rev": "v1.0.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/martian",
|
||||
"Rev": "v2.1.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/pprof",
|
||||
"Rev": "3ea8567a2e57"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/uuid",
|
||||
"Rev": "v1.1.1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/googleapis/gax-go/v2",
|
||||
"Rev": "v2.0.4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/googleapis/gnostic",
|
||||
"Rev": "0c5108395e2d"
|
||||
@@ -116,7 +168,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/golang-lru",
|
||||
"Rev": "v0.5.0"
|
||||
"Rev": "v0.5.1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hpcloud/tail",
|
||||
@@ -130,6 +182,10 @@
|
||||
"ImportPath": "github.com/json-iterator/go",
|
||||
"Rev": "v1.1.7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jstemmer/go-junit-report",
|
||||
"Rev": "af01ea7f8024"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/kisielk/errcheck",
|
||||
"Rev": "v1.2.0"
|
||||
@@ -172,11 +228,11 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo",
|
||||
"Rev": "v1.8.0"
|
||||
"Rev": "v1.10.1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/gomega",
|
||||
"Rev": "v1.5.0"
|
||||
"Rev": "v1.7.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/peterbourgon/diskv",
|
||||
@@ -202,13 +258,25 @@
|
||||
"ImportPath": "github.com/stretchr/testify",
|
||||
"Rev": "v1.3.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "go.opencensus.io",
|
||||
"Rev": "v0.21.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto",
|
||||
"Rev": "e84da0312774"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/exp",
|
||||
"Rev": "509febef88a4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/lint",
|
||||
"Rev": "8f45f776aaf1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net",
|
||||
"Rev": "65e2d4e15006"
|
||||
"Rev": "cdfb69ac37fc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2",
|
||||
@@ -232,12 +300,24 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/tools",
|
||||
"Rev": "aa82965741a9"
|
||||
"Rev": "e65039ee4138"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api",
|
||||
"Rev": "v0.4.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine",
|
||||
"Rev": "v1.5.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/genproto",
|
||||
"Rev": "e7d98fc518a7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/grpc",
|
||||
"Rev": "v1.19.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/check.v1",
|
||||
"Rev": "788fd7840127"
|
||||
@@ -256,15 +336,19 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/yaml.v2",
|
||||
"Rev": "v2.2.2"
|
||||
"Rev": "v2.2.4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "honnef.co/go/tools",
|
||||
"Rev": "3f1c8253044a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api",
|
||||
"Rev": "3ab596449d6f"
|
||||
"Rev": "feb64bed37fc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery",
|
||||
"Rev": "423f5d784010"
|
||||
"Rev": "af6325b3a843"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo",
|
||||
@@ -272,15 +356,15 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/klog",
|
||||
"Rev": "v0.3.1"
|
||||
"Rev": "v1.0.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi",
|
||||
"Rev": "33be087ad058"
|
||||
"Rev": "743ec37842bf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/utils",
|
||||
"Rev": "581e00157fb1"
|
||||
"Rev": "8d271d903fe4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff",
|
||||
|
||||
149
INSTALL.md
149
INSTALL.md
@@ -19,34 +19,7 @@ and detailed dependency version info will be added to your `go.mod` file
|
||||
|
||||
This assumes you are using go modules with go 1.11+.
|
||||
If you get a message like `cannot use path@version syntax in GOPATH mode`,
|
||||
you can choose to [opt into using go modules](#go-modules).
|
||||
If you are using a version of go prior to 1.11, or do not wish to use
|
||||
go modules, you can download `k8s.io/client-go` to your `$GOPATH` instead:
|
||||
|
||||
```sh
|
||||
go get -u k8s.io/client-go/...
|
||||
go get -u k8s.io/apimachinery/...
|
||||
cd $GOPATH/src/k8s.io/client-go
|
||||
git checkout v11.0.0
|
||||
cd $GOPATH/src/k8s.io/apimachinery
|
||||
git checkout kubernetes-1.14.0
|
||||
```
|
||||
|
||||
This downloads a version of `k8s.io/client-go` prior to v1.12.0,
|
||||
which includes most of its dependencies in its `k8s.io/client-go/vendor` path
|
||||
(except for `k8s.io/apimachinery` and `glog`).
|
||||
|
||||
We excluded `k8s.io/apimachinery` and `glog` from `k8s.io/client-go/vendor` to
|
||||
prevent `go get` users from hitting issues like
|
||||
[#19](https://github.com/kubernetes/client-go/issues/19) and
|
||||
[#83](https://github.com/kubernetes/client-go/issues/83). If your project shares
|
||||
other dependencies with client-go, and you hit issues similar to #19 or #83,
|
||||
then you'll need to look down at the next section.
|
||||
|
||||
Note: the official go policy is that libraries should not vendor their
|
||||
dependencies. This was unworkable for us, since our dependencies change and HEAD
|
||||
on every dependency has not necessarily been tested with client-go. In fact,
|
||||
HEAD from all dependencies may not even compile with client-go!
|
||||
see the instructions for [enabling go modules](#enabling-go-modules).
|
||||
|
||||
## Dependency management for the serious (or reluctant) user
|
||||
|
||||
@@ -59,15 +32,10 @@ Reasons why you might need to use a dependency management system:
|
||||
* You want your install to be reproducible. For example, for your CI system or
|
||||
for new team members.
|
||||
|
||||
There are three tools you could in theory use for this. Instructions
|
||||
for each follows.
|
||||
|
||||
### Go modules
|
||||
### Enabling go modules
|
||||
|
||||
Dependency management tools are built into go 1.11+ in the form of [go modules](https://github.com/golang/go/wiki/Modules).
|
||||
These are used by the main Kubernetes repo (>= 1.15) and `client-go` (on master, and v12.0.0+) to manage dependencies.
|
||||
When using `client-go` v12.0.0+ and go 1.11.4+, go modules are the recommended dependency management tool.
|
||||
|
||||
These are used by the main Kubernetes repo (>= `v1.15.0`) and `client-go` (>= `kubernetes-1.15.0`) to manage dependencies.
|
||||
If you are using go 1.11 or 1.12 and are working with a project located within `$GOPATH`,
|
||||
you must opt into using go modules:
|
||||
|
||||
@@ -82,117 +50,16 @@ If you do not already have one, `go mod init` will create one for you:
|
||||
go mod init
|
||||
```
|
||||
|
||||
Indicate which version of `client-go` your project requires.
|
||||
For `client-go` on v12.0.0 (and later), this is a single step:
|
||||
### Add client-go as a dependency
|
||||
|
||||
Indicate which version of `client-go` your project requires (replace `kubernetes-1.15.0` with the desired version):
|
||||
|
||||
```sh
|
||||
go get k8s.io/client-go@v12.0.0
|
||||
```
|
||||
|
||||
For `client-go` prior to v12.0.0, you also need to indicate the required versions of `k8s.io/api` and `k8s.io/apimachinery`:
|
||||
|
||||
```sh
|
||||
go get k8s.io/client-go@v11.0.0 # replace v11.0.0 with the required version (or use kubernetes-1.x.y tags if desired)
|
||||
go get k8s.io/api@kubernetes-1.14.0 # replace kubernetes-1.14.0 with the required version
|
||||
go get k8s.io/apimachinery@kubernetes-1.14.0 # replace kubernetes-1.14.0 with the required version
|
||||
go get k8s.io/client-go@kubernetes-1.15.0
|
||||
```
|
||||
|
||||
You can now import and use the `k8s.io/client-go` APIs in your project.
|
||||
The next time you `go build`, `go test`, or `go run` your project,
|
||||
`k8s.io/client-go` and its dependencies will be downloaded (if needed),
|
||||
and detailed dependency version info will be added to your `go.mod` file
|
||||
(or you can also run `go mod tidy` to do this directly).
|
||||
|
||||
### Glide
|
||||
|
||||
[Glide](https://github.com/Masterminds/glide) is another popular dependency
|
||||
management tool for Go. Glide will manage your /vendor directory, but unlike
|
||||
godep, will not use or modify your $GOPATH (there's no equivalent of
|
||||
`godep restore` or `godep save`).
|
||||
|
||||
Generally, it's best to avoid Glide's many subcommands, favoring modifying
|
||||
Glide's manifest file (`glide.yaml`) directly, then running
|
||||
`glide update --strip-vendor`. First create a `glide.yaml` file at the root of
|
||||
your project:
|
||||
|
||||
```yaml
|
||||
package: ( your project's import path ) # e.g. github.com/foo/bar
|
||||
import:
|
||||
- package: k8s.io/client-go
|
||||
version: v12.0.0 # replace v12.0.0 with the required version
|
||||
```
|
||||
|
||||
Second, add a Go file that imports `client-go` somewhere in your project,
|
||||
otherwise `client-go`'s dependencies will not be added to your project's
|
||||
vendor/. Then run the following command in the same directory as `glide.yaml`:
|
||||
|
||||
```sh
|
||||
glide update --strip-vendor
|
||||
```
|
||||
|
||||
This can also be abbreviated as:
|
||||
|
||||
```sh
|
||||
glide up -v
|
||||
```
|
||||
|
||||
At this point, `k8s.io/client-go` should be added to your project's vendor/.
|
||||
`client-go`'s dependencies should be flattened and be added to your project's
|
||||
vendor/ as well.
|
||||
|
||||
Glide will detect the versions of dependencies `client-go` specified in
|
||||
`client-go`'s Godep.json file, and automatically set the versions of these
|
||||
imports in your /vendor directory. It will also record the detected version of
|
||||
all dependencies in the `glide.lock` file.
|
||||
|
||||
Projects that require a different version of a dependency than `client-go`
|
||||
requests can override the version manually in `glide.yaml`. For example:
|
||||
|
||||
```yaml
|
||||
package: ( your project's import path ) # e.g. github.com/foo/bar
|
||||
import:
|
||||
- package: k8s.io/client-go
|
||||
version: v12.0.0 # replace v12.0.0 with the required version
|
||||
# Use a newer version of go-spew even though client-go wants an old one.
|
||||
- package: github.com/davecgh/go-spew
|
||||
version: v1.1.0
|
||||
```
|
||||
|
||||
After modifying, run `glide up -v` again to re-populate your /vendor directory.
|
||||
|
||||
Optionally, Glide users can also use [`glide-vc`](https://github.com/sgotti/glide-vc)
|
||||
after running `glide up -v` to remove unused files from /vendor.
|
||||
|
||||
### Godep
|
||||
|
||||
[godep](https://github.com/tools/godep) is an older dependency management tool, which was
|
||||
used by the main Kubernetes repo (<= 1.14) and `client-go` (<= v11.0) to manage dependencies.
|
||||
|
||||
Before proceeding with the below instructions, you should ensure that your
|
||||
$GOPATH is empty except for containing your own package and its dependencies,
|
||||
and you have a copy of godep somewhere in your $PATH.
|
||||
|
||||
To install `client-go` and place its dependencies in your `$GOPATH`:
|
||||
|
||||
```sh
|
||||
go get k8s.io/client-go/...
|
||||
cd $GOPATH/src/k8s.io/client-go
|
||||
git checkout v11.0.0 # v11.0.0 or older
|
||||
# cd 1.5 # only necessary with 1.5 and 1.4 clients.
|
||||
godep restore ./...
|
||||
```
|
||||
|
||||
At this point, `client-go`'s dependencies have been placed in your $GOPATH, but
|
||||
if you were to build, `client-go` would still see its own copy of its
|
||||
dependencies in its `vendor` directory. You have two options at this point.
|
||||
|
||||
If you would like to keep dependencies in your own project's vendor directory,
|
||||
then you can continue like this:
|
||||
|
||||
```sh
|
||||
cd $GOPATH/src/<my-pkg>
|
||||
godep save ./...
|
||||
```
|
||||
|
||||
Alternatively, if you want to build using the dependencies in your `$GOPATH`,
|
||||
then `rm -rf vendor/` to remove `client-go`'s copy of its dependencies.
|
||||
(or you can also run `go mod tidy` to do this directly).
|
||||
21
README.md
21
README.md
@@ -2,9 +2,9 @@
|
||||
|
||||
Go clients for talking to a [kubernetes](http://kubernetes.io/) cluster.
|
||||
|
||||
We currently recommend using the v12.0.0 tag. See [INSTALL.md](/INSTALL.md) for
|
||||
detailed installation instructions. `go get k8s.io/client-go/...` works, but
|
||||
will build `master`, which doesn't handle the dependencies well.
|
||||
We recommend using the `kubernetes-1.x.y` tag matching the current Kubernetes release (`kubernetes-1.15.3` at the time this was written).
|
||||
See [INSTALL.md](/INSTALL.md) for detailed installation instructions.
|
||||
`go get k8s.io/client-go@master` works, but will fetch `master`, which may be less stable than a tagged release.
|
||||
|
||||
[![BuildStatus Widget]][BuildStatus Result]
|
||||
[![GoReport Widget]][GoReport Status]
|
||||
@@ -164,8 +164,8 @@ This repository is still a mirror of
|
||||
the code development is still done in the staging area. Since Kubernetes 1.8
|
||||
release, when syncing the code from the staging area, we also sync the Kubernetes
|
||||
version tags to client-go, prefixed with "kubernetes-". For example, if you check
|
||||
out the `kubernetes-v1.8.0` tag in client-go, the code you get is exactly the
|
||||
same as if you check out the `v1.8.0` tag in kubernetes, and change directory to
|
||||
out the `kubernetes-1.15.3` tag in client-go, the code you get is exactly the
|
||||
same as if you check out the `v1.15.3` tag in Kubernetes, and change directory to
|
||||
`staging/src/k8s.io/client-go`. The purpose is to let users quickly find matching
|
||||
commits among published repos, like
|
||||
[sample-apiserver](https://github.com/kubernetes/sample-apiserver),
|
||||
@@ -176,10 +176,13 @@ you care about backwards compatibility.
|
||||
|
||||
### How to get it
|
||||
|
||||
You can use `go get k8s.io/client-go/...` to get client-go, but **you will get
|
||||
the unstable master branch** and `client-go`'s vendored dependencies will not be
|
||||
added to your `$GOPATH`. So we think most users will want to use a dependency
|
||||
management system. See [INSTALL.md](/INSTALL.md) for detailed instructions.
|
||||
Use go1.11+ and fetch the desired version using the `go get` command. For example:
|
||||
|
||||
```
|
||||
go get k8s.io/client-go@kubernetes-1.15.3
|
||||
```
|
||||
|
||||
See [INSTALL.md](/INSTALL.md) for detailed instructions.
|
||||
|
||||
### How to use it
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes 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 deprecated_dynamic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// dynamicCodec is a codec that wraps the standard unstructured codec
|
||||
// with special handling for Status objects.
|
||||
// Deprecated only used by test code and its wrong
|
||||
type dynamicCodec struct{}
|
||||
|
||||
func (dynamicCodec) Decode(data []byte, gvk *schema.GroupVersionKind, obj runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(data, gvk, obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if _, ok := obj.(*metav1.Status); !ok && strings.ToLower(gvk.Kind) == "status" {
|
||||
obj = &metav1.Status{}
|
||||
err := json.Unmarshal(data, obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return obj, gvk, nil
|
||||
}
|
||||
|
||||
func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return unstructured.UnstructuredJSONScheme.Encode(obj, w)
|
||||
}
|
||||
|
||||
// ContentConfig returns a rest.ContentConfig for dynamic types.
|
||||
// Deprecated only used by test code and its wrong
|
||||
func ContentConfig() rest.ContentConfig {
|
||||
// TODO: scheme.Codecs here should become "pkg/apis/server/scheme" which is the minimal core you need
|
||||
// to talk to a kubernetes server
|
||||
jsonInfo, _ := runtime.SerializerInfoForMediaType(scheme.Codecs.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
|
||||
jsonInfo.Serializer = dynamicCodec{}
|
||||
jsonInfo.PrettySerializer = nil
|
||||
return rest.ContentConfig{
|
||||
AcceptContentTypes: runtime.ContentTypeJSON,
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
NegotiatedSerializer: serializer.NegotiatedSerializerWrapper(jsonInfo),
|
||||
}
|
||||
}
|
||||
@@ -511,7 +511,8 @@ func TestWatch(t *testing.T) {
|
||||
t.Errorf("Watch(%q) got query %s. wanted %s", tc.name, r.URL.RawQuery, tc.query)
|
||||
}
|
||||
|
||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, dynamicCodec{}), dynamicCodec{})
|
||||
codec := unstructured.UnstructuredJSONScheme
|
||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, codec), codec)
|
||||
for _, e := range tc.events {
|
||||
enc.Encode(&e)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
"k8s.io/client-go/util/retry"
|
||||
//
|
||||
// Uncomment to load all auth plugins
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
//
|
||||
// Or uncomment to load specific auth plugins
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
"k8s.io/client-go/util/retry"
|
||||
//
|
||||
// Uncomment to load all auth plugins
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
//
|
||||
// Or uncomment to load specific auth plugins
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
"k8s.io/client-go/rest"
|
||||
//
|
||||
// Uncomment to load all auth plugins
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
//
|
||||
// Or uncomment to load specific auth plugins
|
||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
|
||||
@@ -48,6 +48,8 @@ func main() {
|
||||
panic(err.Error())
|
||||
}
|
||||
for {
|
||||
// get pods in all the namespaces by omitting namespace
|
||||
// Or specify namespace to get pods in particular namespace
|
||||
pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
@@ -55,17 +57,17 @@ func main() {
|
||||
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
|
||||
|
||||
// Examples for error handling:
|
||||
// - Use helper functions like e.g. errors.IsNotFound()
|
||||
// - Use helper functions e.g. errors.IsNotFound()
|
||||
// - And/or cast to StatusError and use its properties like e.g. ErrStatus.Message
|
||||
_, err = clientset.CoreV1().Pods("default").Get("example-xxxxx", metav1.GetOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
fmt.Printf("Pod not found\n")
|
||||
fmt.Printf("Pod example-xxxxx not found in default namespace\n")
|
||||
} else if statusError, isStatus := err.(*errors.StatusError); isStatus {
|
||||
fmt.Printf("Error getting pod %v\n", statusError.ErrStatus.Message)
|
||||
} else if err != nil {
|
||||
panic(err.Error())
|
||||
} else {
|
||||
fmt.Printf("Found pod\n")
|
||||
fmt.Printf("Found example-xxxxx pod in default namespace\n")
|
||||
}
|
||||
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
@@ -7,15 +7,16 @@ This example demonstrates how to use the leader election package.
|
||||
Run the following three commands in separate terminals. Each terminal needs a unique `id`.
|
||||
|
||||
```bash
|
||||
# first terminal
|
||||
go run *.go -kubeconfig=/my/config -logtostderr=true -id=1
|
||||
# first terminal
|
||||
go run main.go -kubeconfig=/path/to/kubeconfig -logtostderr=true -lease-lock-name=example -lease-lock-namespace=default -id=1
|
||||
|
||||
# second terminal
|
||||
go run *.go -kubeconfig=/my/config -logtostderr=true -id=2
|
||||
# second terminal
|
||||
go run main.go -kubeconfig=/path/to/kubeconfig -logtostderr=true -lease-lock-name=example -lease-lock-namespace=default -id=2
|
||||
|
||||
# third terminal
|
||||
go run *.go -kubeconfig=/my/config -logtostderr=true -id=3
|
||||
go run main.go -kubeconfig=/path/to/kubeconfig -logtostderr=true -lease-lock-name=example -lease-lock-namespace=default -id=3
|
||||
```
|
||||
|
||||
> You can ignore the `-kubeconfig` flag if you are running these commands in the Kubernetes cluster.
|
||||
|
||||
Now kill the existing leader. You will see from the terminal outputs that one of the remaining two processes will be elected as the new leader.
|
||||
|
||||
@@ -19,21 +19,18 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"k8s.io/client-go/transport"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
@@ -62,13 +59,16 @@ func main() {
|
||||
var id string
|
||||
|
||||
flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file")
|
||||
flag.StringVar(&id, "id", "", "the holder identity name")
|
||||
flag.StringVar(&leaseLockName, "lease-lock-name", "example", "the lease lock resource name")
|
||||
flag.StringVar(&leaseLockNamespace, "lease-lock-namespace", "default", "the lease lock resource namespace")
|
||||
flag.StringVar(&id, "id", uuid.New().String(), "the holder identity name")
|
||||
flag.StringVar(&leaseLockName, "lease-lock-name", "", "the lease lock resource name")
|
||||
flag.StringVar(&leaseLockNamespace, "lease-lock-namespace", "", "the lease lock resource namespace")
|
||||
flag.Parse()
|
||||
|
||||
if id == "" {
|
||||
klog.Fatal("unable to get id (missing id flag).")
|
||||
if leaseLockName == "" {
|
||||
klog.Fatal("unable to get lease lock resource name (missing lease-lock-name flag).")
|
||||
}
|
||||
if leaseLockNamespace == "" {
|
||||
klog.Fatal("unable to get lease lock resource namespace (missing lease-lock-namespace flag).")
|
||||
}
|
||||
|
||||
// leader election uses the Kubernetes API by writing to a
|
||||
@@ -82,6 +82,29 @@ func main() {
|
||||
}
|
||||
client := clientset.NewForConfigOrDie(config)
|
||||
|
||||
run := func(ctx context.Context) {
|
||||
// complete your controller loop here
|
||||
klog.Info("Controller loop...")
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
// use a Go context so we can tell the leaderelection code when we
|
||||
// want to step down
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// listen for interrupts or the Linux SIGTERM signal and cancel
|
||||
// our context, which the leader election code will observe and
|
||||
// step down
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-ch
|
||||
klog.Info("Received termination, signaling shutdown")
|
||||
cancel()
|
||||
}()
|
||||
|
||||
// we use the Lease lock type since edits to Leases are less common
|
||||
// and fewer objects in the cluster watch "all Leases".
|
||||
lock := &resourcelock.LeaseLock{
|
||||
@@ -95,25 +118,6 @@ func main() {
|
||||
},
|
||||
}
|
||||
|
||||
// use a Go context so we can tell the leaderelection code when we
|
||||
// want to step down
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// use a client that will stop allowing new requests once the context ends
|
||||
config.Wrap(transport.ContextCanceller(ctx, fmt.Errorf("the leader is shutting down")))
|
||||
|
||||
// listen for interrupts or the Linux SIGTERM signal and cancel
|
||||
// our context, which the leader election code will observe and
|
||||
// step down
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-ch
|
||||
log.Printf("Received termination, signaling shutdown")
|
||||
cancel()
|
||||
}()
|
||||
|
||||
// start the leader election code loop
|
||||
leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
|
||||
Lock: lock,
|
||||
@@ -131,12 +135,12 @@ func main() {
|
||||
OnStartedLeading: func(ctx context.Context) {
|
||||
// we're notified when we start - this is where you would
|
||||
// usually put your code
|
||||
klog.Infof("%s: leading", id)
|
||||
run(ctx)
|
||||
},
|
||||
OnStoppedLeading: func() {
|
||||
// we can do cleanup here, or after the RunOrDie method
|
||||
// returns
|
||||
klog.Infof("%s: lost", id)
|
||||
// we can do cleanup here
|
||||
klog.Infof("leader lost: %s", id)
|
||||
os.Exit(0)
|
||||
},
|
||||
OnNewLeader: func(identity string) {
|
||||
// we're notified when new leader elected
|
||||
@@ -144,18 +148,8 @@ func main() {
|
||||
// I just got the lock
|
||||
return
|
||||
}
|
||||
klog.Infof("new leader elected: %v", identity)
|
||||
klog.Infof("new leader elected: %s", identity)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// because the context is closed, the client should report errors
|
||||
_, err = client.CoordinationV1().Leases(leaseLockNamespace).Get(leaseLockName, metav1.GetOptions{})
|
||||
if err == nil || !strings.Contains(err.Error(), "the leader is shutting down") {
|
||||
log.Fatalf("%s: expected to get an error when trying to make a client call: %v", id, err)
|
||||
}
|
||||
|
||||
// we no longer hold the lease, so perform any cleanup and then
|
||||
// exit
|
||||
log.Printf("%s: done", id)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
|
||||
35
go.mod
35
go.mod
@@ -5,15 +5,17 @@ module k8s.io/client-go
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/Azure/go-autorest v11.1.2+incompatible
|
||||
cloud.google.com/go v0.38.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.9.0
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda // indirect
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903
|
||||
github.com/golang/protobuf v1.2.0
|
||||
github.com/google/btree v0.0.0-20160524151835-7d79101e329e // indirect
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/google/btree v1.0.0 // indirect
|
||||
github.com/google/gofuzz v1.0.0
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d
|
||||
github.com/gophercloud/gophercloud v0.1.0
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7
|
||||
@@ -22,25 +24,26 @@ require (
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/stretchr/testify v1.3.0
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c
|
||||
google.golang.org/appengine v1.5.0 // indirect
|
||||
k8s.io/api v0.0.0
|
||||
k8s.io/apimachinery v0.0.0
|
||||
k8s.io/klog v0.4.0
|
||||
k8s.io/utils v0.0.0-20190801114015-581e00157fb1
|
||||
k8s.io/api v0.0.0-20191101110233-feb64bed37fc
|
||||
k8s.io/apimachinery v0.0.0-20191025225532-af6325b3a843
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/utils v0.0.0-20191010214722-8d271d903fe4
|
||||
sigs.k8s.io/yaml v1.1.0
|
||||
)
|
||||
|
||||
replace (
|
||||
golang.org/x/crypto => golang.org/x/crypto v0.0.0-20181025213731-e84da0312774
|
||||
golang.org/x/net => golang.org/x/net v0.0.0-20190206173232-65e2d4e15006
|
||||
golang.org/x/lint => golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1
|
||||
golang.org/x/net => golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc
|
||||
golang.org/x/oauth2 => golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a
|
||||
golang.org/x/sync => golang.org/x/sync v0.0.0-20181108010431-42b317875d0f
|
||||
golang.org/x/sys => golang.org/x/sys v0.0.0-20190209173611-3b5209105503
|
||||
golang.org/x/text => golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190313210603-aa82965741a9
|
||||
k8s.io/api => ../api
|
||||
k8s.io/apimachinery => ../apimachinery
|
||||
k8s.io/client-go => ../client-go
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
k8s.io/api => k8s.io/api v0.0.0-20191101110233-feb64bed37fc
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191025225532-af6325b3a843
|
||||
)
|
||||
|
||||
97
go.sum
97
go.sum
@@ -1,16 +1,32 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-autorest v11.1.2+incompatible h1:viZ3tV5l4gE2Sw0xrasFHytCGtzYCrT+um/rrSQ1BfA=
|
||||
github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda h1:NyywMz59neOoVRFDz+ccfKWxn784fiHMDnZSy6T+JXY=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
|
||||
@@ -28,20 +44,30 @@ github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nA
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/btree v0.0.0-20160524151835-7d79101e329e h1:JHB7F/4TJCrYBW8+GZO8VkWDj1jxcWuCl6uxKODiyi4=
|
||||
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=
|
||||
@@ -50,13 +76,16 @@ github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7 h1:6TSoaYExHpe
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
@@ -65,9 +94,11 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
@@ -75,11 +106,11 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -93,10 +124,13 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774 h1:a4tQYYYuK9QdeO/+kEvNYyuR21S+7ve5EANok6hABhI=
|
||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006 h1:bfLnR+k0tq5Lqt6dflRLcZiz6UaXCMt3vhYJ1l4FQ80=
|
||||
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
|
||||
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
@@ -107,10 +141,21 @@ golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+s
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wktg7Jn/a/fNmr33HSj8g=
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190313210603-aa82965741a9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
@@ -125,15 +170,21 @@ gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.0.0-20191101110233-feb64bed37fc/go.mod h1:NMIXwlJTrA+pXie6lv562GUPkluJ4oRGzQfqWBLaceY=
|
||||
k8s.io/apimachinery v0.0.0-20191025225532-af6325b3a843/go.mod h1:gA1T9z4LIup7PIegBwxkF2UYXUNVKhOAPvQWWnAc34k=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ=
|
||||
k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058 h1:di3XCwddOR9cWBNpfgXaskhh6cgJuwcK54rvtwUaC10=
|
||||
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
|
||||
k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE=
|
||||
k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf h1:EYm5AW/UUDbnmnI+gK0TJDVK9qPLhM+sRHYanNKw0EQ=
|
||||
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
k8s.io/utils v0.0.0-20191010214722-8d271d903fe4 h1:Gi+/O1saihwDqnlmC8Vhv1M5Sp4+rbOmK9TbsLn8ZEA=
|
||||
k8s.io/utils v0.0.0-20191010214722-8d271d903fe4/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
|
||||
46
informers/discovery/interface.go
Normal file
46
informers/discovery/interface.go
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package discovery
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/client-go/informers/discovery/v1alpha1"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1alpha1 returns a new v1alpha1.Interface.
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
89
informers/discovery/v1alpha1/endpointslice.go
Normal file
89
informers/discovery/v1alpha1/endpointslice.go
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
kubernetes "k8s.io/client-go/kubernetes"
|
||||
v1alpha1 "k8s.io/client-go/listers/discovery/v1alpha1"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// EndpointSliceInformer provides access to a shared informer and lister for
|
||||
// EndpointSlices.
|
||||
type EndpointSliceInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.EndpointSliceLister
|
||||
}
|
||||
|
||||
type endpointSliceInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewEndpointSliceInformer constructs a new informer for EndpointSlice type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredEndpointSliceInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredEndpointSliceInformer constructs a new informer for EndpointSlice type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredEndpointSliceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.DiscoveryV1alpha1().EndpointSlices(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.DiscoveryV1alpha1().EndpointSlices(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&discoveryv1alpha1.EndpointSlice{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *endpointSliceInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredEndpointSliceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *endpointSliceInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&discoveryv1alpha1.EndpointSlice{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *endpointSliceInformer) Lister() v1alpha1.EndpointSliceLister {
|
||||
return v1alpha1.NewEndpointSliceLister(f.Informer().GetIndexer())
|
||||
}
|
||||
45
informers/discovery/v1alpha1/interface.go
Normal file
45
informers/discovery/v1alpha1/interface.go
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// EndpointSlices returns a EndpointSliceInformer.
|
||||
EndpointSlices() EndpointSliceInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// EndpointSlices returns a EndpointSliceInformer.
|
||||
func (v *version) EndpointSlices() EndpointSliceInformer {
|
||||
return &endpointSliceInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
certificates "k8s.io/client-go/informers/certificates"
|
||||
coordination "k8s.io/client-go/informers/coordination"
|
||||
core "k8s.io/client-go/informers/core"
|
||||
discovery "k8s.io/client-go/informers/discovery"
|
||||
events "k8s.io/client-go/informers/events"
|
||||
extensions "k8s.io/client-go/informers/extensions"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -196,6 +197,7 @@ type SharedInformerFactory interface {
|
||||
Certificates() certificates.Interface
|
||||
Coordination() coordination.Interface
|
||||
Core() core.Interface
|
||||
Discovery() discovery.Interface
|
||||
Events() events.Interface
|
||||
Extensions() extensions.Interface
|
||||
Networking() networking.Interface
|
||||
@@ -239,6 +241,10 @@ func (f *sharedInformerFactory) Core() core.Interface {
|
||||
return core.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Discovery() discovery.Interface {
|
||||
return discovery.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Events() events.Interface {
|
||||
return events.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import (
|
||||
coordinationv1 "k8s.io/api/coordination/v1"
|
||||
coordinationv1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
@@ -202,6 +203,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
case corev1.SchemeGroupVersion.WithResource("serviceaccounts"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Core().V1().ServiceAccounts().Informer()}, nil
|
||||
|
||||
// Group=discovery.k8s.io, Version=v1alpha1
|
||||
case discoveryv1alpha1.SchemeGroupVersion.WithResource("endpointslices"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Discovery().V1alpha1().EndpointSlices().Informer()}, nil
|
||||
|
||||
// Group=events.k8s.io, Version=v1beta1
|
||||
case eventsv1beta1.SchemeGroupVersion.WithResource("events"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Events().V1beta1().Events().Informer()}, nil
|
||||
|
||||
@@ -42,6 +42,7 @@ import (
|
||||
coordinationv1 "k8s.io/client-go/kubernetes/typed/coordination/v1"
|
||||
coordinationv1beta1 "k8s.io/client-go/kubernetes/typed/coordination/v1beta1"
|
||||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
discoveryv1alpha1 "k8s.io/client-go/kubernetes/typed/discovery/v1alpha1"
|
||||
eventsv1beta1 "k8s.io/client-go/kubernetes/typed/events/v1beta1"
|
||||
extensionsv1beta1 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
|
||||
networkingv1 "k8s.io/client-go/kubernetes/typed/networking/v1"
|
||||
@@ -85,6 +86,7 @@ type Interface interface {
|
||||
CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface
|
||||
CoordinationV1() coordinationv1.CoordinationV1Interface
|
||||
CoreV1() corev1.CoreV1Interface
|
||||
DiscoveryV1alpha1() discoveryv1alpha1.DiscoveryV1alpha1Interface
|
||||
EventsV1beta1() eventsv1beta1.EventsV1beta1Interface
|
||||
ExtensionsV1beta1() extensionsv1beta1.ExtensionsV1beta1Interface
|
||||
NetworkingV1() networkingv1.NetworkingV1Interface
|
||||
@@ -128,6 +130,7 @@ type Clientset struct {
|
||||
coordinationV1beta1 *coordinationv1beta1.CoordinationV1beta1Client
|
||||
coordinationV1 *coordinationv1.CoordinationV1Client
|
||||
coreV1 *corev1.CoreV1Client
|
||||
discoveryV1alpha1 *discoveryv1alpha1.DiscoveryV1alpha1Client
|
||||
eventsV1beta1 *eventsv1beta1.EventsV1beta1Client
|
||||
extensionsV1beta1 *extensionsv1beta1.ExtensionsV1beta1Client
|
||||
networkingV1 *networkingv1.NetworkingV1Client
|
||||
@@ -247,6 +250,11 @@ func (c *Clientset) CoreV1() corev1.CoreV1Interface {
|
||||
return c.coreV1
|
||||
}
|
||||
|
||||
// DiscoveryV1alpha1 retrieves the DiscoveryV1alpha1Client
|
||||
func (c *Clientset) DiscoveryV1alpha1() discoveryv1alpha1.DiscoveryV1alpha1Interface {
|
||||
return c.discoveryV1alpha1
|
||||
}
|
||||
|
||||
// EventsV1beta1 retrieves the EventsV1beta1Client
|
||||
func (c *Clientset) EventsV1beta1() eventsv1beta1.EventsV1beta1Interface {
|
||||
return c.eventsV1beta1
|
||||
@@ -433,6 +441,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.discoveryV1alpha1, err = discoveryv1alpha1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.eventsV1beta1, err = eventsv1beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -533,6 +545,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
cs.coordinationV1beta1 = coordinationv1beta1.NewForConfigOrDie(c)
|
||||
cs.coordinationV1 = coordinationv1.NewForConfigOrDie(c)
|
||||
cs.coreV1 = corev1.NewForConfigOrDie(c)
|
||||
cs.discoveryV1alpha1 = discoveryv1alpha1.NewForConfigOrDie(c)
|
||||
cs.eventsV1beta1 = eventsv1beta1.NewForConfigOrDie(c)
|
||||
cs.extensionsV1beta1 = extensionsv1beta1.NewForConfigOrDie(c)
|
||||
cs.networkingV1 = networkingv1.NewForConfigOrDie(c)
|
||||
@@ -578,6 +591,7 @@ func New(c rest.Interface) *Clientset {
|
||||
cs.coordinationV1beta1 = coordinationv1beta1.New(c)
|
||||
cs.coordinationV1 = coordinationv1.New(c)
|
||||
cs.coreV1 = corev1.New(c)
|
||||
cs.discoveryV1alpha1 = discoveryv1alpha1.New(c)
|
||||
cs.eventsV1beta1 = eventsv1beta1.New(c)
|
||||
cs.extensionsV1beta1 = extensionsv1beta1.New(c)
|
||||
cs.networkingV1 = networkingv1.New(c)
|
||||
|
||||
@@ -64,6 +64,8 @@ import (
|
||||
fakecoordinationv1beta1 "k8s.io/client-go/kubernetes/typed/coordination/v1beta1/fake"
|
||||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
fakecorev1 "k8s.io/client-go/kubernetes/typed/core/v1/fake"
|
||||
discoveryv1alpha1 "k8s.io/client-go/kubernetes/typed/discovery/v1alpha1"
|
||||
fakediscoveryv1alpha1 "k8s.io/client-go/kubernetes/typed/discovery/v1alpha1/fake"
|
||||
eventsv1beta1 "k8s.io/client-go/kubernetes/typed/events/v1beta1"
|
||||
fakeeventsv1beta1 "k8s.io/client-go/kubernetes/typed/events/v1beta1/fake"
|
||||
extensionsv1beta1 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
|
||||
@@ -248,6 +250,11 @@ func (c *Clientset) CoreV1() corev1.CoreV1Interface {
|
||||
return &fakecorev1.FakeCoreV1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// DiscoveryV1alpha1 retrieves the DiscoveryV1alpha1Client
|
||||
func (c *Clientset) DiscoveryV1alpha1() discoveryv1alpha1.DiscoveryV1alpha1Interface {
|
||||
return &fakediscoveryv1alpha1.FakeDiscoveryV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// EventsV1beta1 retrieves the EventsV1beta1Client
|
||||
func (c *Clientset) EventsV1beta1() eventsv1beta1.EventsV1beta1Interface {
|
||||
return &fakeeventsv1beta1.FakeEventsV1beta1{Fake: &c.Fake}
|
||||
|
||||
@@ -39,6 +39,7 @@ import (
|
||||
coordinationv1 "k8s.io/api/coordination/v1"
|
||||
coordinationv1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
@@ -87,6 +88,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
coordinationv1beta1.AddToScheme,
|
||||
coordinationv1.AddToScheme,
|
||||
corev1.AddToScheme,
|
||||
discoveryv1alpha1.AddToScheme,
|
||||
eventsv1beta1.AddToScheme,
|
||||
extensionsv1beta1.AddToScheme,
|
||||
networkingv1.AddToScheme,
|
||||
|
||||
@@ -39,6 +39,7 @@ import (
|
||||
coordinationv1 "k8s.io/api/coordination/v1"
|
||||
coordinationv1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
@@ -87,6 +88,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
coordinationv1beta1.AddToScheme,
|
||||
coordinationv1.AddToScheme,
|
||||
corev1.AddToScheme,
|
||||
discoveryv1alpha1.AddToScheme,
|
||||
eventsv1beta1.AddToScheme,
|
||||
extensionsv1beta1.AddToScheme,
|
||||
networkingv1.AddToScheme,
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authenticationapi "k8s.io/api/authentication/v1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeTokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
|
||||
return c.CreateContext(context.Background(), tokenReview)
|
||||
}
|
||||
|
||||
func (c *FakeTokenReviews) CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authenticationapi.SchemeGroupVersion.WithResource("tokenreviews"), tokenReview), &authenticationapi.TokenReview{})
|
||||
return obj.(*authenticationapi.TokenReview), err
|
||||
}
|
||||
|
||||
@@ -17,16 +17,24 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authenticationapi "k8s.io/api/authentication/v1"
|
||||
)
|
||||
|
||||
type TokenReviewExpansion interface {
|
||||
Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
|
||||
CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
|
||||
}
|
||||
|
||||
func (c *tokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
|
||||
return c.CreateContext(context.Background(), tokenReview)
|
||||
}
|
||||
|
||||
func (c *tokenReviews) CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
|
||||
result = &authenticationapi.TokenReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Resource("tokenreviews").
|
||||
Body(tokenReview).
|
||||
Do().
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authenticationapi "k8s.io/api/authentication/v1beta1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeTokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
|
||||
return c.CreateContext(context.Background(), tokenReview)
|
||||
}
|
||||
|
||||
func (c *FakeTokenReviews) CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authenticationapi.SchemeGroupVersion.WithResource("tokenreviews"), tokenReview), &authenticationapi.TokenReview{})
|
||||
return obj.(*authenticationapi.TokenReview), err
|
||||
}
|
||||
|
||||
@@ -17,16 +17,24 @@ limitations under the License.
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authenticationapi "k8s.io/api/authentication/v1beta1"
|
||||
)
|
||||
|
||||
type TokenReviewExpansion interface {
|
||||
Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
|
||||
CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
|
||||
}
|
||||
|
||||
func (c *tokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
|
||||
return c.CreateContext(context.Background(), tokenReview)
|
||||
}
|
||||
|
||||
func (c *tokenReviews) CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
|
||||
result = &authenticationapi.TokenReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Resource("tokenreviews").
|
||||
Body(tokenReview).
|
||||
Do().
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeLocalSubjectAccessReviews) Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *FakeLocalSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewCreateAction(authorizationapi.SchemeGroupVersion.WithResource("localsubjectaccessreviews"), c.ns, sar), &authorizationapi.SubjectAccessReview{})
|
||||
return obj.(*authorizationapi.LocalSubjectAccessReview), err
|
||||
}
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeSelfSubjectAccessReviews) Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *FakeSelfSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("selfsubjectaccessreviews"), sar), &authorizationapi.SelfSubjectAccessReview{})
|
||||
return obj.(*authorizationapi.SelfSubjectAccessReview), err
|
||||
}
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeSelfSubjectRulesReviews) Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
|
||||
return c.CreateContext(context.Background(), srr)
|
||||
}
|
||||
|
||||
func (c *FakeSelfSubjectRulesReviews) CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("selfsubjectrulesreviews"), srr), &authorizationapi.SelfSubjectRulesReview{})
|
||||
return obj.(*authorizationapi.SelfSubjectRulesReview), err
|
||||
}
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeSubjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *FakeSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("subjectaccessreviews"), sar), &authorizationapi.SubjectAccessReview{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
|
||||
@@ -17,16 +17,24 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1"
|
||||
)
|
||||
|
||||
type LocalSubjectAccessReviewExpansion interface {
|
||||
Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error)
|
||||
CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error)
|
||||
}
|
||||
|
||||
func (c *localSubjectAccessReviews) Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *localSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
|
||||
result = &authorizationapi.LocalSubjectAccessReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Namespace(c.ns).
|
||||
Resource("localsubjectaccessreviews").
|
||||
Body(sar).
|
||||
|
||||
@@ -17,16 +17,24 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1"
|
||||
)
|
||||
|
||||
type SelfSubjectAccessReviewExpansion interface {
|
||||
Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error)
|
||||
CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error)
|
||||
}
|
||||
|
||||
func (c *selfSubjectAccessReviews) Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *selfSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
|
||||
result = &authorizationapi.SelfSubjectAccessReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Resource("selfsubjectaccessreviews").
|
||||
Body(sar).
|
||||
Do().
|
||||
|
||||
@@ -17,16 +17,24 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1"
|
||||
)
|
||||
|
||||
type SelfSubjectRulesReviewExpansion interface {
|
||||
Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error)
|
||||
CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error)
|
||||
}
|
||||
|
||||
func (c *selfSubjectRulesReviews) Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
|
||||
return c.CreateContext(context.Background(), srr)
|
||||
}
|
||||
|
||||
func (c *selfSubjectRulesReviews) CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
|
||||
result = &authorizationapi.SelfSubjectRulesReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Resource("selfsubjectrulesreviews").
|
||||
Body(srr).
|
||||
Do().
|
||||
|
||||
@@ -17,17 +17,25 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1"
|
||||
)
|
||||
|
||||
// The SubjectAccessReviewExpansion interface allows manually adding extra methods to the AuthorizationInterface.
|
||||
type SubjectAccessReviewExpansion interface {
|
||||
Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
|
||||
CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
|
||||
}
|
||||
|
||||
func (c *subjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *subjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
|
||||
result = &authorizationapi.SubjectAccessReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Resource("subjectaccessreviews").
|
||||
Body(sar).
|
||||
Do().
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1beta1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeLocalSubjectAccessReviews) Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *FakeLocalSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewCreateAction(authorizationapi.SchemeGroupVersion.WithResource("localsubjectaccessreviews"), c.ns, sar), &authorizationapi.SubjectAccessReview{})
|
||||
return obj.(*authorizationapi.LocalSubjectAccessReview), err
|
||||
}
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1beta1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeSelfSubjectAccessReviews) Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *FakeSelfSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("selfsubjectaccessreviews"), sar), &authorizationapi.SelfSubjectAccessReview{})
|
||||
return obj.(*authorizationapi.SelfSubjectAccessReview), err
|
||||
}
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1beta1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeSelfSubjectRulesReviews) Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
|
||||
return c.CreateContext(context.Background(), srr)
|
||||
}
|
||||
|
||||
func (c *FakeSelfSubjectRulesReviews) CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("selfsubjectrulesreviews"), srr), &authorizationapi.SelfSubjectRulesReview{})
|
||||
return obj.(*authorizationapi.SelfSubjectRulesReview), err
|
||||
}
|
||||
|
||||
@@ -17,11 +17,17 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1beta1"
|
||||
core "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func (c *FakeSubjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *FakeSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
|
||||
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("subjectaccessreviews"), sar), &authorizationapi.SubjectAccessReview{})
|
||||
return obj.(*authorizationapi.SubjectAccessReview), err
|
||||
}
|
||||
|
||||
@@ -17,16 +17,24 @@ limitations under the License.
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1beta1"
|
||||
)
|
||||
|
||||
type LocalSubjectAccessReviewExpansion interface {
|
||||
Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error)
|
||||
CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error)
|
||||
}
|
||||
|
||||
func (c *localSubjectAccessReviews) Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *localSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
|
||||
result = &authorizationapi.LocalSubjectAccessReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Namespace(c.ns).
|
||||
Resource("localsubjectaccessreviews").
|
||||
Body(sar).
|
||||
|
||||
@@ -17,16 +17,24 @@ limitations under the License.
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1beta1"
|
||||
)
|
||||
|
||||
type SelfSubjectAccessReviewExpansion interface {
|
||||
Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error)
|
||||
CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error)
|
||||
}
|
||||
|
||||
func (c *selfSubjectAccessReviews) Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *selfSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
|
||||
result = &authorizationapi.SelfSubjectAccessReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Resource("selfsubjectaccessreviews").
|
||||
Body(sar).
|
||||
Do().
|
||||
|
||||
@@ -17,16 +17,24 @@ limitations under the License.
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1beta1"
|
||||
)
|
||||
|
||||
type SelfSubjectRulesReviewExpansion interface {
|
||||
Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error)
|
||||
CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error)
|
||||
}
|
||||
|
||||
func (c *selfSubjectRulesReviews) Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
|
||||
return c.CreateContext(context.Background(), srr)
|
||||
}
|
||||
|
||||
func (c *selfSubjectRulesReviews) CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
|
||||
result = &authorizationapi.SelfSubjectRulesReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Resource("selfsubjectrulesreviews").
|
||||
Body(srr).
|
||||
Do().
|
||||
|
||||
@@ -17,17 +17,25 @@ limitations under the License.
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
authorizationapi "k8s.io/api/authorization/v1beta1"
|
||||
)
|
||||
|
||||
// The SubjectAccessReviewExpansion interface allows manually adding extra methods to the AuthorizationInterface.
|
||||
type SubjectAccessReviewExpansion interface {
|
||||
Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
|
||||
CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
|
||||
}
|
||||
|
||||
func (c *subjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
|
||||
return c.CreateContext(context.Background(), sar)
|
||||
}
|
||||
|
||||
func (c *subjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
|
||||
result = &authorizationapi.SubjectAccessReview{}
|
||||
err = c.client.Post().
|
||||
Context(ctx).
|
||||
Resource("subjectaccessreviews").
|
||||
Body(sar).
|
||||
Do().
|
||||
|
||||
@@ -104,17 +104,17 @@ func (e *events) Search(scheme *runtime.Scheme, objOrRef runtime.Object) (*v1.Ev
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if e.ns != "" && ref.Namespace != e.ns {
|
||||
if len(e.ns) > 0 && ref.Namespace != e.ns {
|
||||
return nil, fmt.Errorf("won't be able to find any events of namespace '%v' in namespace '%v'", ref.Namespace, e.ns)
|
||||
}
|
||||
stringRefKind := string(ref.Kind)
|
||||
var refKind *string
|
||||
if stringRefKind != "" {
|
||||
if len(stringRefKind) > 0 {
|
||||
refKind = &stringRefKind
|
||||
}
|
||||
stringRefUID := string(ref.UID)
|
||||
var refUID *string
|
||||
if stringRefUID != "" {
|
||||
if len(stringRefUID) > 0 {
|
||||
refUID = &stringRefUID
|
||||
}
|
||||
fieldSelector := e.GetFieldSelector(&ref.Name, &ref.Namespace, refKind, refUID)
|
||||
@@ -124,10 +124,9 @@ func (e *events) Search(scheme *runtime.Scheme, objOrRef runtime.Object) (*v1.Ev
|
||||
// Returns the appropriate field selector based on the API version being used to communicate with the server.
|
||||
// The returned field selector can be used with List and Watch to filter desired events.
|
||||
func (e *events) GetFieldSelector(involvedObjectName, involvedObjectNamespace, involvedObjectKind, involvedObjectUID *string) fields.Selector {
|
||||
apiVersion := e.client.APIVersion().String()
|
||||
field := fields.Set{}
|
||||
if involvedObjectName != nil {
|
||||
field[GetInvolvedObjectNameFieldLabel(apiVersion)] = *involvedObjectName
|
||||
field["involvedObject.name"] = *involvedObjectName
|
||||
}
|
||||
if involvedObjectNamespace != nil {
|
||||
field["involvedObject.namespace"] = *involvedObjectNamespace
|
||||
@@ -142,6 +141,7 @@ func (e *events) GetFieldSelector(involvedObjectName, involvedObjectNamespace, i
|
||||
}
|
||||
|
||||
// Returns the appropriate field label to use for name of the involved object as per the given API version.
|
||||
// DEPRECATED: please use "involvedObject.name" inline.
|
||||
func GetInvolvedObjectNameFieldLabel(version string) string {
|
||||
return "involvedObject.name"
|
||||
}
|
||||
|
||||
89
kubernetes/typed/discovery/v1alpha1/discovery_client.go
Normal file
89
kubernetes/typed/discovery/v1alpha1/discovery_client.go
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type DiscoveryV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
EndpointSlicesGetter
|
||||
}
|
||||
|
||||
// DiscoveryV1alpha1Client is used to interact with features provided by the discovery.k8s.io group.
|
||||
type DiscoveryV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *DiscoveryV1alpha1Client) EndpointSlices(namespace string) EndpointSliceInterface {
|
||||
return newEndpointSlices(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new DiscoveryV1alpha1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*DiscoveryV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DiscoveryV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new DiscoveryV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *DiscoveryV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new DiscoveryV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *DiscoveryV1alpha1Client {
|
||||
return &DiscoveryV1alpha1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1alpha1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *DiscoveryV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
20
kubernetes/typed/discovery/v1alpha1/doc.go
Normal file
20
kubernetes/typed/discovery/v1alpha1/doc.go
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
174
kubernetes/typed/discovery/v1alpha1/endpointslice.go
Normal file
174
kubernetes/typed/discovery/v1alpha1/endpointslice.go
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
scheme "k8s.io/client-go/kubernetes/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// EndpointSlicesGetter has a method to return a EndpointSliceInterface.
|
||||
// A group's client should implement this interface.
|
||||
type EndpointSlicesGetter interface {
|
||||
EndpointSlices(namespace string) EndpointSliceInterface
|
||||
}
|
||||
|
||||
// EndpointSliceInterface has methods to work with EndpointSlice resources.
|
||||
type EndpointSliceInterface interface {
|
||||
Create(*v1alpha1.EndpointSlice) (*v1alpha1.EndpointSlice, error)
|
||||
Update(*v1alpha1.EndpointSlice) (*v1alpha1.EndpointSlice, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha1.EndpointSlice, error)
|
||||
List(opts v1.ListOptions) (*v1alpha1.EndpointSliceList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.EndpointSlice, err error)
|
||||
EndpointSliceExpansion
|
||||
}
|
||||
|
||||
// endpointSlices implements EndpointSliceInterface
|
||||
type endpointSlices struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newEndpointSlices returns a EndpointSlices
|
||||
func newEndpointSlices(c *DiscoveryV1alpha1Client, namespace string) *endpointSlices {
|
||||
return &endpointSlices{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the endpointSlice, and returns the corresponding endpointSlice object, and an error if there is any.
|
||||
func (c *endpointSlices) Get(name string, options v1.GetOptions) (result *v1alpha1.EndpointSlice, err error) {
|
||||
result = &v1alpha1.EndpointSlice{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("endpointslices").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of EndpointSlices that match those selectors.
|
||||
func (c *endpointSlices) List(opts v1.ListOptions) (result *v1alpha1.EndpointSliceList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.EndpointSliceList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("endpointslices").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested endpointSlices.
|
||||
func (c *endpointSlices) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("endpointslices").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a endpointSlice and creates it. Returns the server's representation of the endpointSlice, and an error, if there is any.
|
||||
func (c *endpointSlices) Create(endpointSlice *v1alpha1.EndpointSlice) (result *v1alpha1.EndpointSlice, err error) {
|
||||
result = &v1alpha1.EndpointSlice{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("endpointslices").
|
||||
Body(endpointSlice).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a endpointSlice and updates it. Returns the server's representation of the endpointSlice, and an error, if there is any.
|
||||
func (c *endpointSlices) Update(endpointSlice *v1alpha1.EndpointSlice) (result *v1alpha1.EndpointSlice, err error) {
|
||||
result = &v1alpha1.EndpointSlice{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("endpointslices").
|
||||
Name(endpointSlice.Name).
|
||||
Body(endpointSlice).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the endpointSlice and deletes it. Returns an error if one occurs.
|
||||
func (c *endpointSlices) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("endpointslices").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *endpointSlices) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("endpointslices").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched endpointSlice.
|
||||
func (c *endpointSlices) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.EndpointSlice, err error) {
|
||||
result = &v1alpha1.EndpointSlice{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("endpointslices").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
20
kubernetes/typed/discovery/v1alpha1/fake/doc.go
Normal file
20
kubernetes/typed/discovery/v1alpha1/fake/doc.go
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/client-go/kubernetes/typed/discovery/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeDiscoveryV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeDiscoveryV1alpha1) EndpointSlices(namespace string) v1alpha1.EndpointSliceInterface {
|
||||
return &FakeEndpointSlices{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeDiscoveryV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
128
kubernetes/typed/discovery/v1alpha1/fake/fake_endpointslice.go
Normal file
128
kubernetes/typed/discovery/v1alpha1/fake/fake_endpointslice.go
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeEndpointSlices implements EndpointSliceInterface
|
||||
type FakeEndpointSlices struct {
|
||||
Fake *FakeDiscoveryV1alpha1
|
||||
ns string
|
||||
}
|
||||
|
||||
var endpointslicesResource = schema.GroupVersionResource{Group: "discovery.k8s.io", Version: "v1alpha1", Resource: "endpointslices"}
|
||||
|
||||
var endpointslicesKind = schema.GroupVersionKind{Group: "discovery.k8s.io", Version: "v1alpha1", Kind: "EndpointSlice"}
|
||||
|
||||
// Get takes name of the endpointSlice, and returns the corresponding endpointSlice object, and an error if there is any.
|
||||
func (c *FakeEndpointSlices) Get(name string, options v1.GetOptions) (result *v1alpha1.EndpointSlice, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(endpointslicesResource, c.ns, name), &v1alpha1.EndpointSlice{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.EndpointSlice), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of EndpointSlices that match those selectors.
|
||||
func (c *FakeEndpointSlices) List(opts v1.ListOptions) (result *v1alpha1.EndpointSliceList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(endpointslicesResource, endpointslicesKind, c.ns, opts), &v1alpha1.EndpointSliceList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.EndpointSliceList{ListMeta: obj.(*v1alpha1.EndpointSliceList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.EndpointSliceList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested endpointSlices.
|
||||
func (c *FakeEndpointSlices) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(endpointslicesResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a endpointSlice and creates it. Returns the server's representation of the endpointSlice, and an error, if there is any.
|
||||
func (c *FakeEndpointSlices) Create(endpointSlice *v1alpha1.EndpointSlice) (result *v1alpha1.EndpointSlice, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(endpointslicesResource, c.ns, endpointSlice), &v1alpha1.EndpointSlice{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.EndpointSlice), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a endpointSlice and updates it. Returns the server's representation of the endpointSlice, and an error, if there is any.
|
||||
func (c *FakeEndpointSlices) Update(endpointSlice *v1alpha1.EndpointSlice) (result *v1alpha1.EndpointSlice, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(endpointslicesResource, c.ns, endpointSlice), &v1alpha1.EndpointSlice{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.EndpointSlice), err
|
||||
}
|
||||
|
||||
// Delete takes name of the endpointSlice and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeEndpointSlices) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(endpointslicesResource, c.ns, name), &v1alpha1.EndpointSlice{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeEndpointSlices) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(endpointslicesResource, c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.EndpointSliceList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched endpointSlice.
|
||||
func (c *FakeEndpointSlices) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.EndpointSlice, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(endpointslicesResource, c.ns, name, pt, data, subresources...), &v1alpha1.EndpointSlice{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.EndpointSlice), err
|
||||
}
|
||||
21
kubernetes/typed/discovery/v1alpha1/generated_expansion.go
Normal file
21
kubernetes/typed/discovery/v1alpha1/generated_expansion.go
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type EndpointSliceExpansion interface{}
|
||||
94
listers/discovery/v1alpha1/endpointslice.go
Normal file
94
listers/discovery/v1alpha1/endpointslice.go
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// EndpointSliceLister helps list EndpointSlices.
|
||||
type EndpointSliceLister interface {
|
||||
// List lists all EndpointSlices in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.EndpointSlice, err error)
|
||||
// EndpointSlices returns an object that can list and get EndpointSlices.
|
||||
EndpointSlices(namespace string) EndpointSliceNamespaceLister
|
||||
EndpointSliceListerExpansion
|
||||
}
|
||||
|
||||
// endpointSliceLister implements the EndpointSliceLister interface.
|
||||
type endpointSliceLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewEndpointSliceLister returns a new EndpointSliceLister.
|
||||
func NewEndpointSliceLister(indexer cache.Indexer) EndpointSliceLister {
|
||||
return &endpointSliceLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all EndpointSlices in the indexer.
|
||||
func (s *endpointSliceLister) List(selector labels.Selector) (ret []*v1alpha1.EndpointSlice, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.EndpointSlice))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// EndpointSlices returns an object that can list and get EndpointSlices.
|
||||
func (s *endpointSliceLister) EndpointSlices(namespace string) EndpointSliceNamespaceLister {
|
||||
return endpointSliceNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// EndpointSliceNamespaceLister helps list and get EndpointSlices.
|
||||
type EndpointSliceNamespaceLister interface {
|
||||
// List lists all EndpointSlices in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.EndpointSlice, err error)
|
||||
// Get retrieves the EndpointSlice from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1alpha1.EndpointSlice, error)
|
||||
EndpointSliceNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// endpointSliceNamespaceLister implements the EndpointSliceNamespaceLister
|
||||
// interface.
|
||||
type endpointSliceNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all EndpointSlices in the indexer for a given namespace.
|
||||
func (s endpointSliceNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.EndpointSlice, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.EndpointSlice))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the EndpointSlice from the indexer for a given namespace and name.
|
||||
func (s endpointSliceNamespaceLister) Get(name string) (*v1alpha1.EndpointSlice, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("endpointslice"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.EndpointSlice), nil
|
||||
}
|
||||
27
listers/discovery/v1alpha1/expansion_generated.go
Normal file
27
listers/discovery/v1alpha1/expansion_generated.go
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
// EndpointSliceListerExpansion allows custom methods to be added to
|
||||
// EndpointSliceLister.
|
||||
type EndpointSliceListerExpansion interface{}
|
||||
|
||||
// EndpointSliceNamespaceListerExpansion allows custom methods to be added to
|
||||
// EndpointSliceNamespaceLister.
|
||||
type EndpointSliceNamespaceListerExpansion interface{}
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metainternalversionscheme "k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -63,7 +63,7 @@ func ConfigFor(inConfig *rest.Config) *rest.Config {
|
||||
config := rest.CopyConfig(inConfig)
|
||||
config.AcceptContentTypes = "application/vnd.kubernetes.protobuf,application/json"
|
||||
config.ContentType = "application/vnd.kubernetes.protobuf"
|
||||
config.NegotiatedSerializer = metainternalversion.Codecs.WithoutConversion()
|
||||
config.NegotiatedSerializer = metainternalversionscheme.Codecs.WithoutConversion()
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
@@ -51,11 +51,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*clientauthentication.ExecCredentialSpec)(nil), (*ExecCredentialSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_clientauthentication_ExecCredentialSpec_To_v1beta1_ExecCredentialSpec(a.(*clientauthentication.ExecCredentialSpec), b.(*ExecCredentialSpec), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*ExecCredentialStatus)(nil), (*clientauthentication.ExecCredentialStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus(a.(*ExecCredentialStatus), b.(*clientauthentication.ExecCredentialStatus), scope)
|
||||
}); err != nil {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
def version_x_defs():
|
||||
# This should match the list of packages in kube::version::ldflag
|
||||
stamp_pkgs = [
|
||||
"k8s.io/kubernetes/pkg/version",
|
||||
"k8s.io/component-base/version",
|
||||
# In hack/lib/version.sh, this has a vendor/ prefix. That isn't needed here?
|
||||
"k8s.io/client-go/pkg/version",
|
||||
]
|
||||
|
||||
@@ -20,7 +20,6 @@ reviewers:
|
||||
- resouer
|
||||
- cjcullen
|
||||
- rmmh
|
||||
- lixiaobing10051267
|
||||
- asalkeld
|
||||
- juanvallejo
|
||||
- lojies
|
||||
|
||||
@@ -211,6 +211,12 @@ type TLSClientConfig struct {
|
||||
// CAData holds PEM-encoded bytes (typically read from a root certificates bundle).
|
||||
// CAData takes precedence over CAFile
|
||||
CAData []byte
|
||||
|
||||
// NextProtos is a list of supported application level protocols, in order of preference.
|
||||
// Used to populate tls.Config.NextProtos.
|
||||
// To indicate to the server http/1.1 is preferred over http/2, set to ["http/1.1", "h2"] (though the server is free to ignore that preference).
|
||||
// To use only http/1.1, set to ["http/1.1"].
|
||||
NextProtos []string
|
||||
}
|
||||
|
||||
var _ fmt.Stringer = TLSClientConfig{}
|
||||
@@ -236,6 +242,7 @@ func (c TLSClientConfig) String() string {
|
||||
CertData: c.CertData,
|
||||
KeyData: c.KeyData,
|
||||
CAData: c.CAData,
|
||||
NextProtos: c.NextProtos,
|
||||
}
|
||||
// Explicitly mark non-empty credential fields as redacted.
|
||||
if len(cc.CertData) != 0 {
|
||||
@@ -503,6 +510,7 @@ func AnonymousClientConfig(config *Config) *Config {
|
||||
ServerName: config.ServerName,
|
||||
CAFile: config.TLSClientConfig.CAFile,
|
||||
CAData: config.TLSClientConfig.CAData,
|
||||
NextProtos: config.TLSClientConfig.NextProtos,
|
||||
},
|
||||
RateLimiter: config.RateLimiter,
|
||||
UserAgent: config.UserAgent,
|
||||
@@ -541,6 +549,7 @@ func CopyConfig(config *Config) *Config {
|
||||
CertData: config.TLSClientConfig.CertData,
|
||||
KeyData: config.TLSClientConfig.KeyData,
|
||||
CAData: config.TLSClientConfig.CAData,
|
||||
NextProtos: config.TLSClientConfig.NextProtos,
|
||||
},
|
||||
UserAgent: config.UserAgent,
|
||||
DisableCompression: config.DisableCompression,
|
||||
|
||||
@@ -190,6 +190,10 @@ func (c *fakeCodec) Encode(obj runtime.Object, stream io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *fakeCodec) Identifier() runtime.Identifier {
|
||||
return runtime.Identifier("fake")
|
||||
}
|
||||
|
||||
type fakeRoundTripper struct{}
|
||||
|
||||
func (r *fakeRoundTripper) RoundTrip(*http.Request) (*http.Response, error) {
|
||||
@@ -493,10 +497,11 @@ func TestConfigSprint(t *testing.T) {
|
||||
Env: []clientcmdapi.ExecEnvVar{{Name: "secret", Value: "s3cr3t"}},
|
||||
},
|
||||
TLSClientConfig: TLSClientConfig{
|
||||
CertFile: "a.crt",
|
||||
KeyFile: "a.key",
|
||||
CertData: []byte("fake cert"),
|
||||
KeyData: []byte("fake key"),
|
||||
CertFile: "a.crt",
|
||||
KeyFile: "a.key",
|
||||
CertData: []byte("fake cert"),
|
||||
KeyData: []byte("fake key"),
|
||||
NextProtos: []string{"h2", "http/1.1"},
|
||||
},
|
||||
UserAgent: "gobot",
|
||||
Transport: &fakeRoundTripper{},
|
||||
@@ -508,7 +513,7 @@ func TestConfigSprint(t *testing.T) {
|
||||
Dial: fakeDialFunc,
|
||||
}
|
||||
want := fmt.Sprintf(
|
||||
`&rest.Config{Host:"localhost:8080", APIPath:"v1", ContentConfig:rest.ContentConfig{AcceptContentTypes:"application/json", ContentType:"application/json", GroupVersion:(*schema.GroupVersion)(nil), NegotiatedSerializer:runtime.NegotiatedSerializer(nil)}, Username:"gopher", Password:"--- REDACTED ---", BearerToken:"--- REDACTED ---", BearerTokenFile:"", Impersonate:rest.ImpersonationConfig{UserName:"gopher2", Groups:[]string(nil), Extra:map[string][]string(nil)}, AuthProvider:api.AuthProviderConfig{Name: "gopher", Config: map[string]string{--- REDACTED ---}}, AuthConfigPersister:rest.AuthProviderConfigPersister(--- REDACTED ---), ExecProvider:api.AuthProviderConfig{Command: "sudo", Args: []string{"--- REDACTED ---"}, Env: []ExecEnvVar{--- REDACTED ---}, APIVersion: ""}, TLSClientConfig:rest.sanitizedTLSClientConfig{Insecure:false, ServerName:"", CertFile:"a.crt", KeyFile:"a.key", CAFile:"", CertData:[]uint8{0x2d, 0x2d, 0x2d, 0x20, 0x54, 0x52, 0x55, 0x4e, 0x43, 0x41, 0x54, 0x45, 0x44, 0x20, 0x2d, 0x2d, 0x2d}, KeyData:[]uint8{0x2d, 0x2d, 0x2d, 0x20, 0x52, 0x45, 0x44, 0x41, 0x43, 0x54, 0x45, 0x44, 0x20, 0x2d, 0x2d, 0x2d}, CAData:[]uint8(nil)}, UserAgent:"gobot", DisableCompression:false, Transport:(*rest.fakeRoundTripper)(%p), WrapTransport:(transport.WrapperFunc)(%p), QPS:1, Burst:2, RateLimiter:(*rest.fakeLimiter)(%p), Timeout:3000000000, Dial:(func(context.Context, string, string) (net.Conn, error))(%p)}`,
|
||||
`&rest.Config{Host:"localhost:8080", APIPath:"v1", ContentConfig:rest.ContentConfig{AcceptContentTypes:"application/json", ContentType:"application/json", GroupVersion:(*schema.GroupVersion)(nil), NegotiatedSerializer:runtime.NegotiatedSerializer(nil)}, Username:"gopher", Password:"--- REDACTED ---", BearerToken:"--- REDACTED ---", BearerTokenFile:"", Impersonate:rest.ImpersonationConfig{UserName:"gopher2", Groups:[]string(nil), Extra:map[string][]string(nil)}, AuthProvider:api.AuthProviderConfig{Name: "gopher", Config: map[string]string{--- REDACTED ---}}, AuthConfigPersister:rest.AuthProviderConfigPersister(--- REDACTED ---), ExecProvider:api.AuthProviderConfig{Command: "sudo", Args: []string{"--- REDACTED ---"}, Env: []ExecEnvVar{--- REDACTED ---}, APIVersion: ""}, TLSClientConfig:rest.sanitizedTLSClientConfig{Insecure:false, ServerName:"", CertFile:"a.crt", KeyFile:"a.key", CAFile:"", CertData:[]uint8{0x2d, 0x2d, 0x2d, 0x20, 0x54, 0x52, 0x55, 0x4e, 0x43, 0x41, 0x54, 0x45, 0x44, 0x20, 0x2d, 0x2d, 0x2d}, KeyData:[]uint8{0x2d, 0x2d, 0x2d, 0x20, 0x52, 0x45, 0x44, 0x41, 0x43, 0x54, 0x45, 0x44, 0x20, 0x2d, 0x2d, 0x2d}, CAData:[]uint8(nil), NextProtos:[]string{"h2", "http/1.1"}}, UserAgent:"gobot", DisableCompression:false, Transport:(*rest.fakeRoundTripper)(%p), WrapTransport:(transport.WrapperFunc)(%p), QPS:1, Burst:2, RateLimiter:(*rest.fakeLimiter)(%p), Timeout:3000000000, Dial:(func(context.Context, string, string) (net.Conn, error))(%p)}`,
|
||||
c.Transport, fakeWrapperFunc, c.RateLimiter, fakeDialFunc,
|
||||
)
|
||||
|
||||
|
||||
@@ -691,6 +691,33 @@ func (r *Request) Stream() (io.ReadCloser, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// requestPreflightCheck looks for common programmer errors on Request.
|
||||
//
|
||||
// We tackle here two programmer mistakes. The first one is to try to create
|
||||
// something(POST) using an empty string as namespace with namespaceSet as
|
||||
// true. If namespaceSet is true then namespace should also be defined. The
|
||||
// second mistake is, when under the same circumstances, the programmer tries
|
||||
// to GET, PUT or DELETE a named resource(resourceName != ""), again, if
|
||||
// namespaceSet is true then namespace must not be empty.
|
||||
func (r *Request) requestPreflightCheck() error {
|
||||
if !r.namespaceSet {
|
||||
return nil
|
||||
}
|
||||
if len(r.namespace) > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch r.verb {
|
||||
case "POST":
|
||||
return fmt.Errorf("an empty namespace may not be set during creation")
|
||||
case "GET", "PUT", "DELETE":
|
||||
if len(r.resourceName) > 0 {
|
||||
return fmt.Errorf("an empty namespace may not be set when a resource name is provided")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// request connects to the server and invokes the provided function when a server response is
|
||||
// received. It handles retry behavior and up front validation of requests. It will invoke
|
||||
// fn at most once. It will return an error if a problem occurred prior to connecting to the
|
||||
@@ -707,12 +734,8 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
||||
return r.err
|
||||
}
|
||||
|
||||
// TODO: added to catch programmer errors (invoking operations with an object with an empty namespace)
|
||||
if (r.verb == "GET" || r.verb == "PUT" || r.verb == "DELETE") && r.namespaceSet && len(r.resourceName) > 0 && len(r.namespace) == 0 {
|
||||
return fmt.Errorf("an empty namespace may not be set when a resource name is provided")
|
||||
}
|
||||
if (r.verb == "POST") && r.namespaceSet && len(r.namespace) == 0 {
|
||||
return fmt.Errorf("an empty namespace may not be set during creation")
|
||||
if err := r.requestPreflightCheck(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := r.client
|
||||
@@ -815,8 +838,6 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
||||
// processing.
|
||||
//
|
||||
// Error type:
|
||||
// * If the request can't be constructed, or an error happened earlier while building its
|
||||
// arguments: *RequestConstructionError
|
||||
// * If the server responds with a status: *errors.StatusError or *errors.UnexpectedObjectError
|
||||
// * http.Client.Do errors are returned directly.
|
||||
func (r *Request) Do() Result {
|
||||
|
||||
@@ -1994,3 +1994,66 @@ func defaultResourcePathWithPrefix(prefix, resource, namespace, name string) str
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func TestRequestPreflightCheck(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
verbs []string
|
||||
namespace string
|
||||
resourceName string
|
||||
namespaceSet bool
|
||||
expectsErr bool
|
||||
}{
|
||||
{
|
||||
name: "no namespace set",
|
||||
verbs: []string{"GET", "PUT", "DELETE", "POST"},
|
||||
namespaceSet: false,
|
||||
expectsErr: false,
|
||||
},
|
||||
{
|
||||
name: "empty resource name and namespace",
|
||||
verbs: []string{"GET", "PUT", "DELETE"},
|
||||
namespaceSet: true,
|
||||
expectsErr: false,
|
||||
},
|
||||
{
|
||||
name: "resource name with empty namespace",
|
||||
verbs: []string{"GET", "PUT", "DELETE"},
|
||||
namespaceSet: true,
|
||||
resourceName: "ResourceName",
|
||||
expectsErr: true,
|
||||
},
|
||||
{
|
||||
name: "post empty resource name and namespace",
|
||||
verbs: []string{"POST"},
|
||||
namespaceSet: true,
|
||||
expectsErr: true,
|
||||
},
|
||||
{
|
||||
name: "working requests",
|
||||
verbs: []string{"GET", "PUT", "DELETE", "POST"},
|
||||
namespaceSet: true,
|
||||
resourceName: "ResourceName",
|
||||
namespace: "Namespace",
|
||||
expectsErr: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
for _, verb := range tt.verbs {
|
||||
r := &Request{
|
||||
verb: verb,
|
||||
namespace: tt.namespace,
|
||||
resourceName: tt.resourceName,
|
||||
namespaceSet: tt.namespaceSet,
|
||||
}
|
||||
|
||||
err := r.requestPreflightCheck()
|
||||
hasErr := err != nil
|
||||
if hasErr == tt.expectsErr {
|
||||
return
|
||||
}
|
||||
t.Errorf("%s: expects error: %v, has error: %v", verb, tt.expectsErr, hasErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ func (c *Config) TransportConfig() (*transport.Config, error) {
|
||||
CertData: c.CertData,
|
||||
KeyFile: c.KeyFile,
|
||||
KeyData: c.KeyData,
|
||||
NextProtos: c.NextProtos,
|
||||
},
|
||||
Username: c.Username,
|
||||
Password: c.Password,
|
||||
|
||||
@@ -38,6 +38,11 @@ func (in *TLSClientConfig) DeepCopyInto(out *TLSClientConfig) {
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.NextProtos != nil {
|
||||
in, out := &in.NextProtos, &out.NextProtos
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ func (c *namespacedScaleClient) Get(resource schema.GroupResource, name string)
|
||||
|
||||
result := c.client.clientBase.Get().
|
||||
AbsPath(path).
|
||||
Namespace(c.namespace).
|
||||
NamespaceIfScoped(c.namespace, c.namespace != "").
|
||||
Resource(gvr.Resource).
|
||||
Name(name).
|
||||
SubResource("scale").
|
||||
@@ -191,7 +191,7 @@ func (c *namespacedScaleClient) Update(resource schema.GroupResource, scale *aut
|
||||
|
||||
result := c.client.clientBase.Put().
|
||||
AbsPath(path).
|
||||
Namespace(c.namespace).
|
||||
NamespaceIfScoped(c.namespace, c.namespace != "").
|
||||
Resource(gvr.Resource).
|
||||
Name(scale.Name).
|
||||
SubResource("scale").
|
||||
@@ -211,7 +211,7 @@ func (c *namespacedScaleClient) Patch(gvr schema.GroupVersionResource, name stri
|
||||
groupVersion := gvr.GroupVersion()
|
||||
result := c.client.clientBase.Patch(pt).
|
||||
AbsPath(c.client.apiPathFor(groupVersion)).
|
||||
Namespace(c.namespace).
|
||||
NamespaceIfScoped(c.namespace, c.namespace != "").
|
||||
Resource(gvr.Resource).
|
||||
Name(name).
|
||||
SubResource("scale").
|
||||
|
||||
@@ -23,8 +23,9 @@ import (
|
||||
)
|
||||
|
||||
// ScalesGetter can produce a ScaleInterface
|
||||
// for a particular namespace.
|
||||
type ScalesGetter interface {
|
||||
// Scales produces a ScaleInterface for a particular namespace.
|
||||
// Set namespace to the empty string for non-namespaced resources.
|
||||
Scales(namespace string) ScaleInterface
|
||||
}
|
||||
|
||||
|
||||
@@ -22,23 +22,9 @@ import (
|
||||
v1beta1 "k8s.io/api/apps/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
scheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
// addConversions registers conversions between the internal version
|
||||
// of Scale and supported external versions of Scale.
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus,
|
||||
Convert_v1beta1_ScaleStatus_To_scheme_ScaleStatus,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(in *scheme.ScaleStatus, out *v1beta1.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
out.Selector = nil
|
||||
|
||||
@@ -41,5 +41,5 @@ func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addConversionFuncs)
|
||||
localSchemeBuilder.Register()
|
||||
}
|
||||
|
||||
@@ -54,16 +54,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1beta1.ScaleStatus)(nil), (*scheme.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_ScaleStatus_To_scheme_ScaleStatus(a.(*v1beta1.ScaleStatus), b.(*scheme.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*scheme.ScaleStatus)(nil), (*v1beta1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(a.(*scheme.ScaleStatus), b.(*v1beta1.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*scheme.ScaleStatus)(nil), (*v1beta1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(a.(*scheme.ScaleStatus), b.(*v1beta1.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
|
||||
@@ -22,23 +22,9 @@ import (
|
||||
v1beta2 "k8s.io/api/apps/v1beta2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
scheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
// addConversions registers conversions between the internal version
|
||||
// of Scale and supported external versions of Scale.
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_scheme_ScaleStatus_To_v1beta2_ScaleStatus,
|
||||
Convert_v1beta2_ScaleStatus_To_scheme_ScaleStatus,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func Convert_scheme_ScaleStatus_To_v1beta2_ScaleStatus(in *scheme.ScaleStatus, out *v1beta2.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
out.Selector = nil
|
||||
|
||||
@@ -41,5 +41,5 @@ func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addConversionFuncs)
|
||||
localSchemeBuilder.Register()
|
||||
}
|
||||
|
||||
@@ -54,16 +54,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1beta2.ScaleStatus)(nil), (*scheme.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta2_ScaleStatus_To_scheme_ScaleStatus(a.(*v1beta2.ScaleStatus), b.(*scheme.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*scheme.ScaleStatus)(nil), (*v1beta2.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_scheme_ScaleStatus_To_v1beta2_ScaleStatus(a.(*scheme.ScaleStatus), b.(*v1beta2.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*scheme.ScaleStatus)(nil), (*v1beta2.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_scheme_ScaleStatus_To_v1beta2_ScaleStatus(a.(*scheme.ScaleStatus), b.(*v1beta2.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
|
||||
@@ -22,24 +22,9 @@ import (
|
||||
v1 "k8s.io/api/autoscaling/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
scheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
// addConversions registers conversions between the internal version
|
||||
// of Scale and supported external versions of Scale.
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_scheme_ScaleStatus_To_v1_ScaleStatus,
|
||||
Convert_v1_ScaleStatus_To_scheme_ScaleStatus,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_scheme_ScaleStatus_To_v1_ScaleStatus(in *scheme.ScaleStatus, out *v1.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
out.Selector = ""
|
||||
|
||||
@@ -41,5 +41,5 @@ func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addConversionFuncs)
|
||||
localSchemeBuilder.Register()
|
||||
}
|
||||
|
||||
@@ -54,16 +54,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.ScaleStatus)(nil), (*scheme.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_ScaleStatus_To_scheme_ScaleStatus(a.(*v1.ScaleStatus), b.(*scheme.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*scheme.ScaleStatus)(nil), (*v1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_scheme_ScaleStatus_To_v1_ScaleStatus(a.(*scheme.ScaleStatus), b.(*v1.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*scheme.ScaleStatus)(nil), (*v1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_scheme_ScaleStatus_To_v1_ScaleStatus(a.(*scheme.ScaleStatus), b.(*v1.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
|
||||
@@ -22,23 +22,9 @@ import (
|
||||
v1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
scheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
// addConversions registers conversions between the internal version
|
||||
// of Scale and supported external versions of Scale.
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus,
|
||||
Convert_v1beta1_ScaleStatus_To_scheme_ScaleStatus,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(in *scheme.ScaleStatus, out *v1beta1.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
out.Selector = nil
|
||||
|
||||
@@ -41,5 +41,5 @@ func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addConversionFuncs)
|
||||
localSchemeBuilder.Register()
|
||||
}
|
||||
|
||||
@@ -54,16 +54,6 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1beta1.ScaleStatus)(nil), (*scheme.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_ScaleStatus_To_scheme_ScaleStatus(a.(*v1beta1.ScaleStatus), b.(*scheme.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*scheme.ScaleStatus)(nil), (*v1beta1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(a.(*scheme.ScaleStatus), b.(*v1beta1.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*scheme.ScaleStatus)(nil), (*v1beta1.ScaleStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(a.(*scheme.ScaleStatus), b.(*v1beta1.ScaleStatus), scope)
|
||||
}); err != nil {
|
||||
|
||||
@@ -28,15 +28,15 @@ import (
|
||||
// Scale represents a scaling request for a resource.
|
||||
type Scale struct {
|
||||
metav1.TypeMeta
|
||||
// Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata.
|
||||
// Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
|
||||
// +optional
|
||||
metav1.ObjectMeta
|
||||
|
||||
// defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status.
|
||||
// defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
|
||||
// +optional
|
||||
Spec ScaleSpec
|
||||
|
||||
// current status of the scale. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status. Read-only.
|
||||
// current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.
|
||||
// +optional
|
||||
Status ScaleStatus
|
||||
}
|
||||
|
||||
@@ -439,8 +439,8 @@ func (a ActionImpl) GetSubresource() string {
|
||||
return a.Subresource
|
||||
}
|
||||
func (a ActionImpl) Matches(verb, resource string) bool {
|
||||
return strings.ToLower(verb) == strings.ToLower(a.Verb) &&
|
||||
strings.ToLower(resource) == strings.ToLower(a.Resource.Resource)
|
||||
return strings.EqualFold(verb, a.Verb) &&
|
||||
strings.EqualFold(resource, a.Resource.Resource)
|
||||
}
|
||||
func (a ActionImpl) DeepCopy() Action {
|
||||
ret := a
|
||||
|
||||
@@ -248,7 +248,7 @@ func (t *tracker) List(gvr schema.GroupVersionResource, gvk schema.GroupVersionK
|
||||
return list, nil
|
||||
}
|
||||
|
||||
matchingObjs, err := filterByNamespaceAndName(objs, ns, "")
|
||||
matchingObjs, err := filterByNamespace(objs, ns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -282,9 +282,19 @@ func (t *tracker) Get(gvr schema.GroupVersionResource, ns, name string) (runtime
|
||||
return nil, errNotFound
|
||||
}
|
||||
|
||||
matchingObjs, err := filterByNamespaceAndName(objs, ns, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var matchingObjs []runtime.Object
|
||||
for _, obj := range objs {
|
||||
acc, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if acc.GetNamespace() != ns {
|
||||
continue
|
||||
}
|
||||
if acc.GetName() != name {
|
||||
continue
|
||||
}
|
||||
matchingObjs = append(matchingObjs, obj)
|
||||
}
|
||||
if len(matchingObjs) == 0 {
|
||||
return nil, errNotFound
|
||||
@@ -472,10 +482,10 @@ func (t *tracker) Delete(gvr schema.GroupVersionResource, ns, name string) error
|
||||
return errors.NewNotFound(gvr.GroupResource(), name)
|
||||
}
|
||||
|
||||
// filterByNamespaceAndName returns all objects in the collection that
|
||||
// match provided namespace and name. Empty namespace matches
|
||||
// filterByNamespace returns all objects in the collection that
|
||||
// match provided namespace. Empty namespace matches
|
||||
// non-namespaced objects.
|
||||
func filterByNamespaceAndName(objs []runtime.Object, ns, name string) ([]runtime.Object, error) {
|
||||
func filterByNamespace(objs []runtime.Object, ns string) ([]runtime.Object, error) {
|
||||
var res []runtime.Object
|
||||
|
||||
for _, obj := range objs {
|
||||
@@ -486,9 +496,6 @@ func filterByNamespaceAndName(objs []runtime.Object, ns, name string) ([]runtime
|
||||
if ns != "" && acc.GetNamespace() != ns {
|
||||
continue
|
||||
}
|
||||
if name != "" && acc.GetName() != name {
|
||||
continue
|
||||
}
|
||||
res = append(res, obj)
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -204,7 +205,8 @@ func TestWatchCallMultipleInvocation(t *testing.T) {
|
||||
event := <-w.ResultChan()
|
||||
accessor, err := meta.Accessor(event.Object)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
break
|
||||
}
|
||||
assert.Equal(t, c.op, event.Type, "watch event mismatched")
|
||||
assert.Equal(t, c.name, accessor.GetName(), "watched object mismatch")
|
||||
@@ -273,3 +275,50 @@ func TestPatchWithMissingObject(t *testing.T) {
|
||||
assert.Nil(t, node)
|
||||
assert.EqualError(t, err, `nodes "node-1" not found`)
|
||||
}
|
||||
|
||||
func TestGetWithExactMatch(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
|
||||
constructObject := func(s schema.GroupVersionResource, name, namespace string) (*unstructured.Unstructured, schema.GroupVersionResource) {
|
||||
obj := getArbitraryResource(s, name, namespace)
|
||||
gvks, _, err := scheme.ObjectKinds(obj)
|
||||
assert.Nil(t, err)
|
||||
gvr, _ := meta.UnsafeGuessKindToResource(gvks[0])
|
||||
return obj, gvr
|
||||
}
|
||||
|
||||
var err error
|
||||
// Object with empty namespace
|
||||
o := NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
nodeResource := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "node"}
|
||||
node, gvr := constructObject(nodeResource, "node", "")
|
||||
|
||||
assert.Nil(t, o.Add(node))
|
||||
|
||||
// Exact match
|
||||
_, err = o.Get(gvr, "", "node")
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Unexpected namespace provided
|
||||
_, err = o.Get(gvr, "ns", "node")
|
||||
assert.NotNil(t, err)
|
||||
errNotFound := errors.NewNotFound(gvr.GroupResource(), "node")
|
||||
assert.EqualError(t, err, errNotFound.Error())
|
||||
|
||||
// Object with non-empty namespace
|
||||
o = NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
podResource := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pod"}
|
||||
pod, gvr := constructObject(podResource, "pod", "default")
|
||||
assert.Nil(t, o.Add(pod))
|
||||
|
||||
// Exact match
|
||||
_, err = o.Get(gvr, "default", "pod")
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Missing namespace
|
||||
_, err = o.Get(gvr, "", "pod")
|
||||
assert.NotNil(t, err)
|
||||
errNotFound = errors.NewNotFound(gvr.GroupResource(), "pod")
|
||||
assert.EqualError(t, err, errNotFound.Error())
|
||||
}
|
||||
|
||||
6
tools/cache/OWNERS
vendored
6
tools/cache/OWNERS
vendored
@@ -33,8 +33,6 @@ reviewers:
|
||||
- madhusudancs
|
||||
- hongchaodeng
|
||||
- krousey
|
||||
- markturansky
|
||||
- fgrzadkowski
|
||||
- xiang90
|
||||
- mml
|
||||
- ingvagabund
|
||||
@@ -42,10 +40,6 @@ reviewers:
|
||||
- jessfraz
|
||||
- david-mcmahon
|
||||
- mfojtik
|
||||
- '249043822'
|
||||
- lixiaobing10051267
|
||||
- ddysher
|
||||
- mqliang
|
||||
- feihujiang
|
||||
- sdminonne
|
||||
- ncdc
|
||||
|
||||
2
tools/cache/controller.go
vendored
2
tools/cache/controller.go
vendored
@@ -131,6 +131,8 @@ func (c *controller) HasSynced() bool {
|
||||
}
|
||||
|
||||
func (c *controller) LastSyncResourceVersion() string {
|
||||
c.reflectorMutex.RLock()
|
||||
defer c.reflectorMutex.RUnlock()
|
||||
if c.reflector == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
21
tools/cache/delta_fifo.go
vendored
21
tools/cache/delta_fifo.go
vendored
@@ -295,13 +295,6 @@ func isDeletionDup(a, b *Delta) *Delta {
|
||||
return b
|
||||
}
|
||||
|
||||
// willObjectBeDeletedLocked returns true only if the last delta for the
|
||||
// given object is Delete. Caller must lock first.
|
||||
func (f *DeltaFIFO) willObjectBeDeletedLocked(id string) bool {
|
||||
deltas := f.items[id]
|
||||
return len(deltas) > 0 && deltas[len(deltas)-1].Type == Deleted
|
||||
}
|
||||
|
||||
// queueActionLocked appends to the delta list for the object.
|
||||
// Caller must lock first.
|
||||
func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) error {
|
||||
@@ -310,13 +303,6 @@ func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) err
|
||||
return KeyError{obj, err}
|
||||
}
|
||||
|
||||
// If object is supposed to be deleted (last event is Deleted),
|
||||
// then we should ignore Sync events, because it would result in
|
||||
// recreation of this object.
|
||||
if actionType == Sync && f.willObjectBeDeletedLocked(id) {
|
||||
return nil
|
||||
}
|
||||
|
||||
newDeltas := append(f.items[id], Delta{actionType, obj})
|
||||
newDeltas = dedupDeltas(newDeltas)
|
||||
|
||||
@@ -539,13 +525,6 @@ func (f *DeltaFIFO) Resync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *DeltaFIFO) syncKey(key string) error {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
return f.syncKeyLocked(key)
|
||||
}
|
||||
|
||||
func (f *DeltaFIFO) syncKeyLocked(key string) error {
|
||||
obj, exists, err := f.knownObjects.GetByKey(key)
|
||||
if err != nil {
|
||||
|
||||
27
tools/cache/delta_fifo_test.go
vendored
27
tools/cache/delta_fifo_test.go
vendored
@@ -85,6 +85,33 @@ func TestDeltaFIFO_basic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestDeltaFIFO_replaceWithDeleteDeltaIn tests that a `Sync` delta for an
|
||||
// object `O` with ID `X` is added when .Replace is called and `O` is among the
|
||||
// replacement objects even if the DeltaFIFO already stores in terminal position
|
||||
// a delta of type `Delete` for ID `X`. Not adding the `Sync` delta causes
|
||||
// SharedIndexInformers to miss `O`'s create notification, see https://github.com/kubernetes/kubernetes/issues/83810
|
||||
// for more details.
|
||||
func TestDeltaFIFO_replaceWithDeleteDeltaIn(t *testing.T) {
|
||||
oldObj := mkFifoObj("foo", 1)
|
||||
newObj := mkFifoObj("foo", 2)
|
||||
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, keyLookupFunc(func() []testFifoObject {
|
||||
return []testFifoObject{oldObj}
|
||||
}))
|
||||
|
||||
f.Delete(oldObj)
|
||||
f.Replace([]interface{}{newObj}, "")
|
||||
|
||||
actualDeltas := Pop(f)
|
||||
expectedDeltas := Deltas{
|
||||
Delta{Type: Deleted, Object: oldObj},
|
||||
Delta{Type: Sync, Object: newObj},
|
||||
}
|
||||
if !reflect.DeepEqual(expectedDeltas, actualDeltas) {
|
||||
t.Errorf("expected %#v, got %#v", expectedDeltas, actualDeltas)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFO_requeueOnPop(t *testing.T) {
|
||||
f := NewDeltaFIFO(testFifoObjectKeyFunc, nil)
|
||||
|
||||
|
||||
83
tools/cache/reflector.go
vendored
83
tools/cache/reflector.go
vendored
@@ -22,19 +22,19 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
"k8s.io/apimachinery/pkg/util/naming"
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
@@ -43,15 +43,22 @@ import (
|
||||
"k8s.io/utils/trace"
|
||||
)
|
||||
|
||||
const defaultExpectedTypeName = "<unspecified>"
|
||||
|
||||
// Reflector watches a specified resource and causes all changes to be reflected in the given store.
|
||||
type Reflector struct {
|
||||
// name identifies this reflector. By default it will be a file:line if possible.
|
||||
name string
|
||||
// metrics tracks basic metric information about the reflector
|
||||
metrics *reflectorMetrics
|
||||
|
||||
// The name of the type we expect to place in the store. The name
|
||||
// will be the stringification of expectedGVK if provided, and the
|
||||
// stringification of expectedType otherwise. It is for display
|
||||
// only, and should not be used for parsing or comparison.
|
||||
expectedTypeName string
|
||||
// The type of object we expect to place in the store.
|
||||
expectedType reflect.Type
|
||||
// The GVK of the object we expect to place in the store if unstructured.
|
||||
expectedGVK *schema.GroupVersionKind
|
||||
// The destination to sync up with the watch source
|
||||
store Store
|
||||
// listerWatcher is used to perform lists and watches.
|
||||
@@ -104,14 +111,35 @@ func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{},
|
||||
name: name,
|
||||
listerWatcher: lw,
|
||||
store: store,
|
||||
expectedType: reflect.TypeOf(expectedType),
|
||||
period: time.Second,
|
||||
resyncPeriod: resyncPeriod,
|
||||
clock: &clock.RealClock{},
|
||||
}
|
||||
r.setExpectedType(expectedType)
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Reflector) setExpectedType(expectedType interface{}) {
|
||||
r.expectedType = reflect.TypeOf(expectedType)
|
||||
if r.expectedType == nil {
|
||||
r.expectedTypeName = defaultExpectedTypeName
|
||||
return
|
||||
}
|
||||
|
||||
r.expectedTypeName = r.expectedType.String()
|
||||
|
||||
if obj, ok := expectedType.(*unstructured.Unstructured); ok {
|
||||
// Use gvk to check that watch event objects are of the desired type.
|
||||
gvk := obj.GroupVersionKind()
|
||||
if gvk.Empty() {
|
||||
klog.V(4).Infof("Reflector from %s configured with expectedType of *unstructured.Unstructured with empty GroupVersionKind.", r.name)
|
||||
return
|
||||
}
|
||||
r.expectedGVK = &gvk
|
||||
r.expectedTypeName = gvk.String()
|
||||
}
|
||||
}
|
||||
|
||||
// internalPackages are packages that ignored when creating a default reflector name. These packages are in the common
|
||||
// call chains to NewReflector, so they'd be low entropy names for reflectors
|
||||
var internalPackages = []string{"client-go/tools/cache/"}
|
||||
@@ -119,7 +147,7 @@ var internalPackages = []string{"client-go/tools/cache/"}
|
||||
// Run starts a watch and handles watch events. Will restart the watch if it is closed.
|
||||
// Run will exit when stopCh is closed.
|
||||
func (r *Reflector) Run(stopCh <-chan struct{}) {
|
||||
klog.V(3).Infof("Starting reflector %v (%s) from %s", r.expectedType, r.resyncPeriod, r.name)
|
||||
klog.V(3).Infof("Starting reflector %v (%s) from %s", r.expectedTypeName, r.resyncPeriod, r.name)
|
||||
wait.Until(func() {
|
||||
if err := r.ListAndWatch(stopCh); err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
@@ -131,9 +159,6 @@ var (
|
||||
// nothing will ever be sent down this channel
|
||||
neverExitWatch <-chan time.Time = make(chan time.Time)
|
||||
|
||||
// Used to indicate that watching stopped so that a resync could happen.
|
||||
errorResyncRequested = errors.New("resync channel fired")
|
||||
|
||||
// Used to indicate that watching stopped because of a signal from the stop
|
||||
// channel passed in from a client of the reflector.
|
||||
errorStopRequested = errors.New("Stop requested")
|
||||
@@ -157,7 +182,7 @@ func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) {
|
||||
// and then use the resource version to watch.
|
||||
// It returns error if ListAndWatch didn't even try to initialize watch.
|
||||
func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
|
||||
klog.V(3).Infof("Listing and watching %v from %s", r.expectedType, r.name)
|
||||
klog.V(3).Infof("Listing and watching %v from %s", r.expectedTypeName, r.name)
|
||||
var resourceVersion string
|
||||
|
||||
// Explicitly set "0" as resource version - it's fine for the List()
|
||||
@@ -198,7 +223,7 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
|
||||
case <-listCh:
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: Failed to list %v: %v", r.name, r.expectedType, err)
|
||||
return fmt.Errorf("%s: Failed to list %v: %v", r.name, r.expectedTypeName, err)
|
||||
}
|
||||
initTrace.Step("Objects listed")
|
||||
listMetaInterface, err := meta.ListAccessor(list)
|
||||
@@ -277,21 +302,17 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
|
||||
case io.EOF:
|
||||
// watch closed normally
|
||||
case io.ErrUnexpectedEOF:
|
||||
klog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.expectedType, err)
|
||||
klog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.expectedTypeName, err)
|
||||
default:
|
||||
utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.expectedType, err))
|
||||
utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.expectedTypeName, err))
|
||||
}
|
||||
// If this is "connection refused" error, it means that most likely apiserver is not responsive.
|
||||
// It doesn't make sense to re-list all objects because most likely we will be able to restart
|
||||
// watch where we ended.
|
||||
// If that's the case wait and resend watch request.
|
||||
if urlError, ok := err.(*url.Error); ok {
|
||||
if opError, ok := urlError.Err.(*net.OpError); ok {
|
||||
if errno, ok := opError.Err.(syscall.Errno); ok && errno == syscall.ECONNREFUSED {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if utilnet.IsConnectionRefused(err) {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -300,9 +321,9 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
|
||||
if err != errorStopRequested {
|
||||
switch {
|
||||
case apierrs.IsResourceExpired(err):
|
||||
klog.V(4).Infof("%s: watch of %v ended with: %v", r.name, r.expectedType, err)
|
||||
klog.V(4).Infof("%s: watch of %v ended with: %v", r.name, r.expectedTypeName, err)
|
||||
default:
|
||||
klog.Warningf("%s: watch of %v ended with: %v", r.name, r.expectedType, err)
|
||||
klog.Warningf("%s: watch of %v ended with: %v", r.name, r.expectedTypeName, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -342,9 +363,17 @@ loop:
|
||||
if event.Type == watch.Error {
|
||||
return apierrs.FromObject(event.Object)
|
||||
}
|
||||
if e, a := r.expectedType, reflect.TypeOf(event.Object); e != nil && e != a {
|
||||
utilruntime.HandleError(fmt.Errorf("%s: expected type %v, but watch event object had type %v", r.name, e, a))
|
||||
continue
|
||||
if r.expectedType != nil {
|
||||
if e, a := r.expectedType, reflect.TypeOf(event.Object); e != a {
|
||||
utilruntime.HandleError(fmt.Errorf("%s: expected type %v, but watch event object had type %v", r.name, e, a))
|
||||
continue
|
||||
}
|
||||
}
|
||||
if r.expectedGVK != nil {
|
||||
if e, a := *r.expectedGVK, event.Object.GetObjectKind().GroupVersionKind(); e != a {
|
||||
utilruntime.HandleError(fmt.Errorf("%s: expected gvk %v, but watch event object had gvk %v", r.name, e, a))
|
||||
continue
|
||||
}
|
||||
}
|
||||
meta, err := meta.Accessor(event.Object)
|
||||
if err != nil {
|
||||
@@ -386,7 +415,7 @@ loop:
|
||||
if watchDuration < 1*time.Second && eventCount == 0 {
|
||||
return fmt.Errorf("very short watch: %s: Unexpected watch close - watch lasted less than a second and no items received", r.name)
|
||||
}
|
||||
klog.V(4).Infof("%s: Watch close - %v total %v items received", r.name, r.expectedType, eventCount)
|
||||
klog.V(4).Infof("%s: Watch close - %v total %v items received", r.name, r.expectedTypeName, eventCount)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
13
tools/cache/reflector_metrics.go
vendored
13
tools/cache/reflector_metrics.go
vendored
@@ -47,19 +47,6 @@ func (noopMetric) Dec() {}
|
||||
func (noopMetric) Observe(float64) {}
|
||||
func (noopMetric) Set(float64) {}
|
||||
|
||||
type reflectorMetrics struct {
|
||||
numberOfLists CounterMetric
|
||||
listDuration SummaryMetric
|
||||
numberOfItemsInList SummaryMetric
|
||||
|
||||
numberOfWatches CounterMetric
|
||||
numberOfShortWatches CounterMetric
|
||||
watchDuration SummaryMetric
|
||||
numberOfItemsInWatch SummaryMetric
|
||||
|
||||
lastResourceVersion GaugeMetric
|
||||
}
|
||||
|
||||
// MetricsProvider generates various metrics used by the reflector.
|
||||
type MetricsProvider interface {
|
||||
NewListsMetric(name string) CounterMetric
|
||||
|
||||
60
tools/cache/reflector_test.go
vendored
60
tools/cache/reflector_test.go
vendored
@@ -20,13 +20,16 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
)
|
||||
@@ -430,3 +433,58 @@ func TestReflectorWatchListPageSize(t *testing.T) {
|
||||
t.Errorf("Expected 10 results, got %d", len(results))
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorSetExpectedType(t *testing.T) {
|
||||
obj := &unstructured.Unstructured{}
|
||||
gvk := schema.GroupVersionKind{
|
||||
Group: "mygroup",
|
||||
Version: "v1",
|
||||
Kind: "MyKind",
|
||||
}
|
||||
obj.SetGroupVersionKind(gvk)
|
||||
testCases := map[string]struct {
|
||||
inputType interface{}
|
||||
expectedTypeName string
|
||||
expectedType reflect.Type
|
||||
expectedGVK *schema.GroupVersionKind
|
||||
}{
|
||||
"Nil type": {
|
||||
expectedTypeName: defaultExpectedTypeName,
|
||||
},
|
||||
"Normal type": {
|
||||
inputType: &v1.Pod{},
|
||||
expectedTypeName: "*v1.Pod",
|
||||
expectedType: reflect.TypeOf(&v1.Pod{}),
|
||||
},
|
||||
"Unstructured type without GVK": {
|
||||
inputType: &unstructured.Unstructured{},
|
||||
expectedTypeName: "*unstructured.Unstructured",
|
||||
expectedType: reflect.TypeOf(&unstructured.Unstructured{}),
|
||||
},
|
||||
"Unstructured type with GVK": {
|
||||
inputType: obj,
|
||||
expectedTypeName: gvk.String(),
|
||||
expectedType: reflect.TypeOf(&unstructured.Unstructured{}),
|
||||
expectedGVK: &gvk,
|
||||
},
|
||||
}
|
||||
for testName, tc := range testCases {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
r := &Reflector{}
|
||||
r.setExpectedType(tc.inputType)
|
||||
if tc.expectedType != r.expectedType {
|
||||
t.Fatalf("Expected expectedType %v, got %v", tc.expectedType, r.expectedType)
|
||||
}
|
||||
if tc.expectedTypeName != r.expectedTypeName {
|
||||
t.Fatalf("Expected expectedTypeName %v, got %v", tc.expectedTypeName, r.expectedTypeName)
|
||||
}
|
||||
gvkNotEqual := (tc.expectedGVK == nil) != (r.expectedGVK == nil)
|
||||
if tc.expectedGVK != nil && r.expectedGVK != nil {
|
||||
gvkNotEqual = *tc.expectedGVK != *r.expectedGVK
|
||||
}
|
||||
if gvkNotEqual {
|
||||
t.Fatalf("Expected expectedGVK %v, got %v", tc.expectedGVK, r.expectedGVK)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
18
tools/cache/shared_informer.go
vendored
18
tools/cache/shared_informer.go
vendored
@@ -190,10 +190,26 @@ const (
|
||||
initialBufferSize = 1024
|
||||
)
|
||||
|
||||
// WaitForNamedCacheSync is a wrapper around WaitForCacheSync that generates log messages
|
||||
// indicating that the caller identified by name is waiting for syncs, followed by
|
||||
// either a successful or failed sync.
|
||||
func WaitForNamedCacheSync(controllerName string, stopCh <-chan struct{}, cacheSyncs ...InformerSynced) bool {
|
||||
klog.Infof("Waiting for caches to sync for %s", controllerName)
|
||||
|
||||
if !WaitForCacheSync(stopCh, cacheSyncs...) {
|
||||
utilruntime.HandleError(fmt.Errorf("unable to sync caches for %s", controllerName))
|
||||
return false
|
||||
}
|
||||
|
||||
klog.Infof("Caches are synced for %s ", controllerName)
|
||||
return true
|
||||
}
|
||||
|
||||
// WaitForCacheSync waits for caches to populate. It returns true if it was successful, false
|
||||
// if the controller should shutdown
|
||||
// callers should prefer WaitForNamedCacheSync()
|
||||
func WaitForCacheSync(stopCh <-chan struct{}, cacheSyncs ...InformerSynced) bool {
|
||||
err := wait.PollUntil(syncedPollPeriod,
|
||||
err := wait.PollImmediateUntil(syncedPollPeriod,
|
||||
func() (bool, error) {
|
||||
for _, syncFunc := range cacheSyncs {
|
||||
if !syncFunc() {
|
||||
|
||||
@@ -449,13 +449,15 @@ func (config *DirectClientConfig) getCluster() (clientcmdapi.Cluster, error) {
|
||||
return clientcmdapi.Cluster{}, fmt.Errorf("cluster %q does not exist", clusterInfoName)
|
||||
}
|
||||
mergo.MergeWithOverwrite(mergedClusterInfo, config.overrides.ClusterInfo)
|
||||
// An override of --insecure-skip-tls-verify=true and no accompanying CA/CA data should clear already-set CA/CA data
|
||||
// otherwise, a kubeconfig containing a CA reference would return an error that "CA and insecure-skip-tls-verify couldn't both be set"
|
||||
// * An override of --insecure-skip-tls-verify=true and no accompanying CA/CA data should clear already-set CA/CA data
|
||||
// otherwise, a kubeconfig containing a CA reference would return an error that "CA and insecure-skip-tls-verify couldn't both be set".
|
||||
// * An override of --certificate-authority should also override TLS skip settings and CA data, otherwise existing CA data will take precedence.
|
||||
caLen := len(config.overrides.ClusterInfo.CertificateAuthority)
|
||||
caDataLen := len(config.overrides.ClusterInfo.CertificateAuthorityData)
|
||||
if config.overrides.ClusterInfo.InsecureSkipTLSVerify && caLen == 0 && caDataLen == 0 {
|
||||
mergedClusterInfo.CertificateAuthority = ""
|
||||
mergedClusterInfo.CertificateAuthorityData = nil
|
||||
if config.overrides.ClusterInfo.InsecureSkipTLSVerify || caLen > 0 || caDataLen > 0 {
|
||||
mergedClusterInfo.InsecureSkipTLSVerify = config.overrides.ClusterInfo.InsecureSkipTLSVerify
|
||||
mergedClusterInfo.CertificateAuthority = config.overrides.ClusterInfo.CertificateAuthority
|
||||
mergedClusterInfo.CertificateAuthorityData = config.overrides.ClusterInfo.CertificateAuthorityData
|
||||
}
|
||||
|
||||
return *mergedClusterInfo, nil
|
||||
|
||||
@@ -148,7 +148,7 @@ func TestInsecureOverridesCA(t *testing.T) {
|
||||
|
||||
actualCfg, err := clientBuilder.ClientConfig()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
matchBoolArg(true, actualCfg.Insecure, t)
|
||||
@@ -156,6 +156,30 @@ func TestInsecureOverridesCA(t *testing.T) {
|
||||
matchByteArg(nil, actualCfg.TLSClientConfig.CAData, t)
|
||||
}
|
||||
|
||||
func TestCAOverridesCAData(t *testing.T) {
|
||||
file, err := ioutil.TempFile("", "my.ca")
|
||||
if err != nil {
|
||||
t.Fatalf("could not create tempfile: %v", err)
|
||||
}
|
||||
defer os.Remove(file.Name())
|
||||
|
||||
config := createCAValidTestConfig()
|
||||
clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{
|
||||
ClusterInfo: clientcmdapi.Cluster{
|
||||
CertificateAuthority: file.Name(),
|
||||
},
|
||||
}, nil)
|
||||
|
||||
actualCfg, err := clientBuilder.ClientConfig()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
matchBoolArg(false, actualCfg.Insecure, t)
|
||||
matchStringArg(file.Name(), actualCfg.TLSClientConfig.CAFile, t)
|
||||
matchByteArg(nil, actualCfg.TLSClientConfig.CAData, t)
|
||||
}
|
||||
|
||||
func TestMergeContext(t *testing.T) {
|
||||
const namespace = "overridden-namespace"
|
||||
|
||||
@@ -458,7 +482,6 @@ func TestCreateCleanDefaultCluster(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateMissingContextNoDefault(t *testing.T) {
|
||||
const expectedErrorContains = "Context was not found for specified context"
|
||||
config := createValidTestConfig()
|
||||
clientBuilder := NewNonInteractiveClientConfig(*config, "not-present", &ConfigOverrides{}, nil)
|
||||
|
||||
|
||||
@@ -24,19 +24,6 @@ import (
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
)
|
||||
|
||||
type testLoader struct {
|
||||
ClientConfigLoader
|
||||
|
||||
called bool
|
||||
config *clientcmdapi.Config
|
||||
err error
|
||||
}
|
||||
|
||||
func (l *testLoader) Load() (*clientcmdapi.Config, error) {
|
||||
l.called = true
|
||||
return l.config, l.err
|
||||
}
|
||||
|
||||
type testClientConfig struct {
|
||||
rawconfig *clientcmdapi.Config
|
||||
config *restclient.Config
|
||||
|
||||
@@ -185,9 +185,10 @@ func validateClusterInfo(clusterName string, clusterInfo clientcmdapi.Cluster) [
|
||||
}
|
||||
if len(clusterInfo.CertificateAuthority) != 0 {
|
||||
clientCertCA, err := os.Open(clusterInfo.CertificateAuthority)
|
||||
defer clientCertCA.Close()
|
||||
if err != nil {
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read certificate-authority %v for %v due to %v", clusterInfo.CertificateAuthority, clusterName, err))
|
||||
} else {
|
||||
defer clientCertCA.Close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,16 +224,18 @@ func validateAuthInfo(authInfoName string, authInfo clientcmdapi.AuthInfo) []err
|
||||
|
||||
if len(authInfo.ClientCertificate) != 0 {
|
||||
clientCertFile, err := os.Open(authInfo.ClientCertificate)
|
||||
defer clientCertFile.Close()
|
||||
if err != nil {
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read client-cert %v for %v due to %v", authInfo.ClientCertificate, authInfoName, err))
|
||||
} else {
|
||||
defer clientCertFile.Close()
|
||||
}
|
||||
}
|
||||
if len(authInfo.ClientKey) != 0 {
|
||||
clientKeyFile, err := os.Open(authInfo.ClientKey)
|
||||
defer clientKeyFile.Close()
|
||||
if err != nil {
|
||||
validationErrors = append(validationErrors, fmt.Errorf("unable to read client-key %v for %v due to %v", authInfo.ClientKey, authInfoName, err))
|
||||
} else {
|
||||
defer clientKeyFile.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ type eventKey struct {
|
||||
action string
|
||||
reason string
|
||||
reportingController string
|
||||
reportingInstance string
|
||||
regarding corev1.ObjectReference
|
||||
related corev1.ObjectReference
|
||||
}
|
||||
@@ -103,6 +102,10 @@ func newBroadcaster(sink EventSink, sleepDuration time.Duration, eventCache map[
|
||||
}
|
||||
}
|
||||
|
||||
func (e *eventBroadcasterImpl) Shutdown() {
|
||||
e.Broadcaster.Shutdown()
|
||||
}
|
||||
|
||||
// refreshExistingEventSeries refresh events TTL
|
||||
func (e *eventBroadcasterImpl) refreshExistingEventSeries() {
|
||||
// TODO: Investigate whether lock contention won't be a problem
|
||||
@@ -111,7 +114,9 @@ func (e *eventBroadcasterImpl) refreshExistingEventSeries() {
|
||||
for isomorphicKey, event := range e.eventCache {
|
||||
if event.Series != nil {
|
||||
if recordedEvent, retry := recordEvent(e.sink, event); !retry {
|
||||
e.eventCache[isomorphicKey] = recordedEvent
|
||||
if recordedEvent != nil {
|
||||
e.eventCache[isomorphicKey] = recordedEvent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,9 +208,9 @@ func recordEvent(sink EventSink, event *v1beta1.Event) (*v1beta1.Event, bool) {
|
||||
var err error
|
||||
isEventSeries := event.Series != nil
|
||||
if isEventSeries {
|
||||
patch, err := createPatchBytesForSeries(event)
|
||||
if err != nil {
|
||||
klog.Errorf("Unable to calculate diff, no merge is possible: %v", err)
|
||||
patch, patchBytesErr := createPatchBytesForSeries(event)
|
||||
if patchBytesErr != nil {
|
||||
klog.Errorf("Unable to calculate diff, no merge is possible: %v", patchBytesErr)
|
||||
return nil, false
|
||||
}
|
||||
newEvent, err = sink.Patch(event, patch)
|
||||
@@ -262,7 +267,6 @@ func getKey(event *v1beta1.Event) eventKey {
|
||||
action: event.Action,
|
||||
reason: event.Reason,
|
||||
reportingController: event.ReportingController,
|
||||
reportingInstance: event.ReportingInstance,
|
||||
regarding: event.Regarding,
|
||||
}
|
||||
if event.Related != nil {
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
k8sruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
ref "k8s.io/client-go/tools/reference"
|
||||
)
|
||||
|
||||
@@ -168,17 +169,17 @@ func TestEventSeriesf(t *testing.T) {
|
||||
if item.expectUpdate {
|
||||
actualEvent := <-patchEvent
|
||||
t.Logf("%v - validating event affected by patch request", index)
|
||||
validateEventSerie(strconv.Itoa(index), true, actualEvent, item.expect, t)
|
||||
validateEvent(strconv.Itoa(index), true, actualEvent, item.expect, t)
|
||||
} else {
|
||||
actualEvent := <-createEvent
|
||||
t.Logf("%v - validating event affected by a create request", index)
|
||||
validateEventSerie(strconv.Itoa(index), false, actualEvent, item.expect, t)
|
||||
validateEvent(strconv.Itoa(index), false, actualEvent, item.expect, t)
|
||||
}
|
||||
}
|
||||
close(stopCh)
|
||||
}
|
||||
|
||||
func validateEventSerie(messagePrefix string, expectedUpdate bool, actualEvent *v1beta1.Event, expectedEvent *v1beta1.Event, t *testing.T) {
|
||||
func validateEvent(messagePrefix string, expectedUpdate bool, actualEvent *v1beta1.Event, expectedEvent *v1beta1.Event, t *testing.T) {
|
||||
recvEvent := *actualEvent
|
||||
|
||||
// Just check that the timestamp was set.
|
||||
@@ -299,51 +300,72 @@ func TestRefreshExistingEventSeries(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
LastObservedTime := metav1.MicroTime{Time: time.Now().Add(-9 * time.Minute)}
|
||||
|
||||
createEvent := make(chan *v1beta1.Event, 10)
|
||||
updateEvent := make(chan *v1beta1.Event, 10)
|
||||
patchEvent := make(chan *v1beta1.Event, 10)
|
||||
testEvents := testEventSeriesSink{
|
||||
OnCreate: func(event *v1beta1.Event) (*v1beta1.Event, error) {
|
||||
createEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
OnUpdate: func(event *v1beta1.Event) (*v1beta1.Event, error) {
|
||||
updateEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
OnPatch: func(event *v1beta1.Event, patch []byte) (*v1beta1.Event, error) {
|
||||
// event we receive is already patched, usually the sink uses it
|
||||
//only to retrieve the name and namespace, here we'll use it directly.
|
||||
patchEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
}
|
||||
cache := map[eventKey]*v1beta1.Event{}
|
||||
eventBroadcaster := newBroadcaster(&testEvents, 0, cache).(*eventBroadcasterImpl)
|
||||
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, "k8s.io/kube-foo").(*recorderImpl)
|
||||
cachedEvent := recorder.makeEvent(regarding, related, metav1.MicroTime{time.Now()}, v1.EventTypeNormal, "test", "some verbose message: 1", "eventTest", "eventTest-"+hostname, "started")
|
||||
cachedEvent.Series = &v1beta1.EventSeries{
|
||||
Count: 10,
|
||||
LastObservedTime: LastObservedTime,
|
||||
}
|
||||
cacheKey := getKey(cachedEvent)
|
||||
cache[cacheKey] = cachedEvent
|
||||
|
||||
eventBroadcaster.refreshExistingEventSeries()
|
||||
select {
|
||||
case <-patchEvent:
|
||||
t.Logf("validating event affected by patch request")
|
||||
eventBroadcaster.mu.Lock()
|
||||
defer eventBroadcaster.mu.Unlock()
|
||||
if len(cache) != 1 {
|
||||
t.Errorf("cache should be with same size, but instead got a size of %v", len(cache))
|
||||
table := []struct {
|
||||
patchFunc func(event *v1beta1.Event, patch []byte) (*v1beta1.Event, error)
|
||||
}{
|
||||
{
|
||||
patchFunc: func(event *v1beta1.Event, patch []byte) (*v1beta1.Event, error) {
|
||||
// event we receive is already patched, usually the sink uses it
|
||||
//only to retrieve the name and namespace, here we'll use it directly.
|
||||
patchEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
patchFunc: func(event *v1beta1.Event, patch []byte) (*v1beta1.Event, error) {
|
||||
// we simulate an apiserver error here
|
||||
patchEvent <- nil
|
||||
return nil, &restclient.RequestConstructionError{}
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, item := range table {
|
||||
testEvents := testEventSeriesSink{
|
||||
OnCreate: func(event *v1beta1.Event) (*v1beta1.Event, error) {
|
||||
createEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
OnUpdate: func(event *v1beta1.Event) (*v1beta1.Event, error) {
|
||||
updateEvent <- event
|
||||
return event, nil
|
||||
},
|
||||
OnPatch: item.patchFunc,
|
||||
}
|
||||
// check that we emitted only one event
|
||||
if len(patchEvent) != 0 || len(createEvent) != 0 || len(updateEvent) != 0 {
|
||||
t.Errorf("exactly one event should be emitted, but got %v", len(patchEvent))
|
||||
cache := map[eventKey]*v1beta1.Event{}
|
||||
eventBroadcaster := newBroadcaster(&testEvents, 0, cache).(*eventBroadcasterImpl)
|
||||
recorder := eventBroadcaster.NewRecorder(scheme.Scheme, "k8s.io/kube-foo").(*recorderImpl)
|
||||
cachedEvent := recorder.makeEvent(regarding, related, metav1.MicroTime{time.Now()}, v1.EventTypeNormal, "test", "some verbose message: 1", "eventTest", "eventTest-"+hostname, "started")
|
||||
cachedEvent.Series = &v1beta1.EventSeries{
|
||||
Count: 10,
|
||||
LastObservedTime: LastObservedTime,
|
||||
}
|
||||
cacheKey := getKey(cachedEvent)
|
||||
cache[cacheKey] = cachedEvent
|
||||
|
||||
eventBroadcaster.refreshExistingEventSeries()
|
||||
select {
|
||||
case <-patchEvent:
|
||||
t.Logf("validating event affected by patch request")
|
||||
eventBroadcaster.mu.Lock()
|
||||
defer eventBroadcaster.mu.Unlock()
|
||||
if len(cache) != 1 {
|
||||
t.Errorf("cache should be with same size, but instead got a size of %v", len(cache))
|
||||
}
|
||||
// check that we emitted only one event
|
||||
if len(patchEvent) != 0 || len(createEvent) != 0 || len(updateEvent) != 0 {
|
||||
t.Errorf("exactly one event should be emitted, but got %v", len(patchEvent))
|
||||
}
|
||||
cacheEvent, exists := cache[cacheKey]
|
||||
|
||||
if cacheEvent == nil || !exists {
|
||||
t.Errorf("expected event to exist and not being nil, but instead event: %v and exists: %v", cacheEvent, exists)
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("timeout after %v", wait.ForeverTestTimeout)
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("timeout after %v", wait.ForeverTestTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,9 @@ type EventRecorder interface {
|
||||
// should be in UpperCamelCase format (starting with a capital letter). "reason" will be used
|
||||
// to automate handling of events, so imagine people writing switch statements to handle them.
|
||||
// You want to make that easy.
|
||||
// 'action' explains what happened with regarding/what action did the ReportingController
|
||||
// (ReportingController is a type of a Controller reporting an Event, e.g. k8s.io/node-controller, k8s.io/kubelet.)
|
||||
// take in regarding's name; it should be in UpperCamelCase format (starting with a capital letter).
|
||||
// 'note' is intended to be human readable.
|
||||
Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...interface{})
|
||||
}
|
||||
@@ -51,6 +54,9 @@ type EventBroadcaster interface {
|
||||
// NOTE: events received on your eventHandler should be copied before being used.
|
||||
// TODO: figure out if this can be removed.
|
||||
StartEventWatcher(eventHandler func(event runtime.Object)) func()
|
||||
|
||||
// Shutdown shuts down the broadcaster
|
||||
Shutdown()
|
||||
}
|
||||
|
||||
// EventSink knows how to store events (client-go implements it.)
|
||||
|
||||
@@ -12,4 +12,3 @@ reviewers:
|
||||
- timothysc
|
||||
- ingvagabund
|
||||
- resouer
|
||||
- goltermann
|
||||
|
||||
@@ -21,9 +21,10 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"net/http"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
rl "k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type fakeLock struct {
|
||||
@@ -31,8 +32,8 @@ type fakeLock struct {
|
||||
}
|
||||
|
||||
// Get is a dummy to allow us to have a fakeLock for testing.
|
||||
func (fl *fakeLock) Get() (ler *rl.LeaderElectionRecord, err error) {
|
||||
return nil, nil
|
||||
func (fl *fakeLock) Get() (ler *rl.LeaderElectionRecord, rawRecord []byte, err error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
// Create is a dummy to allow us to have a fakeLock for testing.
|
||||
|
||||
@@ -53,9 +53,9 @@ limitations under the License.
|
||||
package leaderelection
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -176,8 +176,9 @@ type LeaderCallbacks struct {
|
||||
type LeaderElector struct {
|
||||
config LeaderElectionConfig
|
||||
// internal bookkeeping
|
||||
observedRecord rl.LeaderElectionRecord
|
||||
observedTime time.Time
|
||||
observedRecord rl.LeaderElectionRecord
|
||||
observedRawRecord []byte
|
||||
observedTime time.Time
|
||||
// used to implement OnNewLeader(), may lag slightly from the
|
||||
// value observedRecord.HolderIdentity if the transition has
|
||||
// not yet been reported.
|
||||
@@ -324,7 +325,7 @@ func (le *LeaderElector) tryAcquireOrRenew() bool {
|
||||
}
|
||||
|
||||
// 1. obtain or create the ElectionRecord
|
||||
oldLeaderElectionRecord, err := le.config.Lock.Get()
|
||||
oldLeaderElectionRecord, oldLeaderElectionRawRecord, err := le.config.Lock.Get()
|
||||
if err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
klog.Errorf("error retrieving resource lock %v: %v", le.config.Lock.Describe(), err)
|
||||
@@ -340,8 +341,9 @@ func (le *LeaderElector) tryAcquireOrRenew() bool {
|
||||
}
|
||||
|
||||
// 2. Record obtained, check the Identity & Time
|
||||
if !reflect.DeepEqual(le.observedRecord, *oldLeaderElectionRecord) {
|
||||
if !bytes.Equal(le.observedRawRecord, oldLeaderElectionRawRecord) {
|
||||
le.observedRecord = *oldLeaderElectionRecord
|
||||
le.observedRawRecord = oldLeaderElectionRawRecord
|
||||
le.observedTime = le.clock.Now()
|
||||
}
|
||||
if len(oldLeaderElectionRecord.HolderIdentity) > 0 &&
|
||||
@@ -365,6 +367,7 @@ func (le *LeaderElector) tryAcquireOrRenew() bool {
|
||||
klog.Errorf("Failed to update lock: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
le.observedRecord = leaderElectionRecord
|
||||
le.observedTime = le.clock.Now()
|
||||
return true
|
||||
|
||||
@@ -37,7 +37,7 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
)
|
||||
|
||||
func createLockObject(objectType, namespace, name string, record rl.LeaderElectionRecord) (obj runtime.Object) {
|
||||
func createLockObject(t *testing.T, objectType, namespace, name string, record rl.LeaderElectionRecord) (obj runtime.Object) {
|
||||
objectMeta := metav1.ObjectMeta{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
@@ -59,7 +59,7 @@ func createLockObject(objectType, namespace, name string, record rl.LeaderElecti
|
||||
spec := rl.LeaderElectionRecordToLeaseSpec(&record)
|
||||
obj = &coordinationv1.Lease{ObjectMeta: objectMeta, Spec: spec}
|
||||
default:
|
||||
panic("unexpected objType:" + objectType)
|
||||
t.Fatal("unexpected objType:" + objectType)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -69,6 +69,12 @@ func TestTryAcquireOrRenewEndpoints(t *testing.T) {
|
||||
testTryAcquireOrRenew(t, "endpoints")
|
||||
}
|
||||
|
||||
type Reactor struct {
|
||||
verb string
|
||||
objectType string
|
||||
reaction fakeclient.ReactionFunc
|
||||
}
|
||||
|
||||
func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
future := time.Now().Add(1000 * time.Hour)
|
||||
past := time.Now().Add(-1000 * time.Hour)
|
||||
@@ -77,10 +83,7 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
name string
|
||||
observedRecord rl.LeaderElectionRecord
|
||||
observedTime time.Time
|
||||
reactors []struct {
|
||||
verb string
|
||||
reaction fakeclient.ReactionFunc
|
||||
}
|
||||
reactors []Reactor
|
||||
|
||||
expectSuccess bool
|
||||
transitionLeader bool
|
||||
@@ -88,10 +91,7 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
}{
|
||||
{
|
||||
name: "acquire from no object",
|
||||
reactors: []struct {
|
||||
verb string
|
||||
reaction fakeclient.ReactionFunc
|
||||
}{
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
@@ -110,14 +110,11 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
},
|
||||
{
|
||||
name: "acquire from unled object",
|
||||
reactors: []struct {
|
||||
verb string
|
||||
reaction fakeclient.ReactionFunc
|
||||
}{
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{}), nil
|
||||
return true, createLockObject(t, objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -134,14 +131,11 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
},
|
||||
{
|
||||
name: "acquire from led, unacked object",
|
||||
reactors: []struct {
|
||||
verb string
|
||||
reaction fakeclient.ReactionFunc
|
||||
}{
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
return true, createLockObject(t, objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -160,14 +154,11 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
},
|
||||
{
|
||||
name: "acquire from empty led, acked object",
|
||||
reactors: []struct {
|
||||
verb string
|
||||
reaction fakeclient.ReactionFunc
|
||||
}{
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: ""}), nil
|
||||
return true, createLockObject(t, objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: ""}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -185,14 +176,11 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
},
|
||||
{
|
||||
name: "don't acquire from led, acked object",
|
||||
reactors: []struct {
|
||||
verb string
|
||||
reaction fakeclient.ReactionFunc
|
||||
}{
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
return true, createLockObject(t, objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -203,14 +191,11 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
},
|
||||
{
|
||||
name: "renew already acquired object",
|
||||
reactors: []struct {
|
||||
verb string
|
||||
reaction fakeclient.ReactionFunc
|
||||
}{
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
return true, createLockObject(t, objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -282,13 +267,14 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
},
|
||||
},
|
||||
}
|
||||
observedRawRecord := GetRawRecordOrDie(t, objectType, test.observedRecord)
|
||||
le := &LeaderElector{
|
||||
config: lec,
|
||||
observedRecord: test.observedRecord,
|
||||
observedTime: test.observedTime,
|
||||
clock: clock.RealClock{},
|
||||
config: lec,
|
||||
observedRecord: test.observedRecord,
|
||||
observedRawRecord: observedRawRecord,
|
||||
observedTime: test.observedTime,
|
||||
clock: clock.RealClock{},
|
||||
}
|
||||
|
||||
if test.expectSuccess != le.tryAcquireOrRenew() {
|
||||
t.Errorf("unexpected result of tryAcquireOrRenew: [succeeded=%v]", !test.expectSuccess)
|
||||
}
|
||||
@@ -352,3 +338,560 @@ func TestLeaseSpecToLeaderElectionRecordRoundTrip(t *testing.T) {
|
||||
t.Errorf("diff: %v", diff.ObjectReflectDiff(oldRecord, newRecord))
|
||||
}
|
||||
}
|
||||
|
||||
func multiLockType(t *testing.T, objectType string) (primaryType, secondaryType string) {
|
||||
switch objectType {
|
||||
case rl.EndpointsLeasesResourceLock:
|
||||
return rl.EndpointsResourceLock, rl.LeasesResourceLock
|
||||
case rl.ConfigMapsLeasesResourceLock:
|
||||
return rl.ConfigMapsResourceLock, rl.LeasesResourceLock
|
||||
default:
|
||||
t.Fatal("unexpected objType:" + objectType)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetRawRecordOrDie(t *testing.T, objectType string, ler rl.LeaderElectionRecord) (ret []byte) {
|
||||
var err error
|
||||
switch objectType {
|
||||
case "endpoints", "configmaps", "leases":
|
||||
ret, err = json.Marshal(ler)
|
||||
if err != nil {
|
||||
t.Fatalf("lock %s get raw record %v failed: %v", objectType, ler, err)
|
||||
}
|
||||
case "endpointsleases", "configmapsleases":
|
||||
recordBytes, err := json.Marshal(ler)
|
||||
if err != nil {
|
||||
t.Fatalf("lock %s get raw record %v failed: %v", objectType, ler, err)
|
||||
}
|
||||
ret = rl.ConcatRawRecord(recordBytes, recordBytes)
|
||||
default:
|
||||
t.Fatal("unexpected objType:" + objectType)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
future := time.Now().Add(1000 * time.Hour)
|
||||
past := time.Now().Add(-1000 * time.Hour)
|
||||
primaryType, secondaryType := multiLockType(t, objectType)
|
||||
tests := []struct {
|
||||
name string
|
||||
observedRecord rl.LeaderElectionRecord
|
||||
observedRawRecord []byte
|
||||
observedTime time.Time
|
||||
reactors []Reactor
|
||||
|
||||
expectSuccess bool
|
||||
transitionLeader bool
|
||||
outHolder string
|
||||
}{
|
||||
{
|
||||
name: "acquire from no object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "create",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.CreateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "create",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.CreateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
expectSuccess: true,
|
||||
outHolder: "baz",
|
||||
},
|
||||
{
|
||||
name: "acquire from unled old object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "create",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.CreateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
expectSuccess: true,
|
||||
transitionLeader: true,
|
||||
outHolder: "baz",
|
||||
},
|
||||
{
|
||||
name: "acquire from unled transition object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
expectSuccess: true,
|
||||
transitionLeader: true,
|
||||
outHolder: "baz",
|
||||
},
|
||||
{
|
||||
name: "acquire from led, unack old object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "create",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.CreateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
|
||||
observedRawRecord: GetRawRecordOrDie(t, primaryType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
|
||||
observedTime: past,
|
||||
|
||||
expectSuccess: true,
|
||||
transitionLeader: true,
|
||||
outHolder: "baz",
|
||||
},
|
||||
{
|
||||
name: "acquire from led, unack transition object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
|
||||
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
|
||||
observedTime: past,
|
||||
|
||||
expectSuccess: true,
|
||||
transitionLeader: true,
|
||||
outHolder: "baz",
|
||||
},
|
||||
{
|
||||
name: "acquire from conflict led, ack transition object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
|
||||
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
|
||||
observedTime: future,
|
||||
|
||||
expectSuccess: false,
|
||||
outHolder: rl.UnknownLeader,
|
||||
},
|
||||
{
|
||||
name: "acquire from led, unack unknown object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
observedRecord: rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader},
|
||||
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}),
|
||||
observedTime: past,
|
||||
|
||||
expectSuccess: true,
|
||||
transitionLeader: true,
|
||||
outHolder: "baz",
|
||||
},
|
||||
{
|
||||
name: "don't acquire from led, ack old object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.NewNotFound(action.(fakeclient.GetAction).GetResource().GroupResource(), action.(fakeclient.GetAction).GetName())
|
||||
},
|
||||
},
|
||||
},
|
||||
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
|
||||
observedRawRecord: GetRawRecordOrDie(t, primaryType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
|
||||
observedTime: future,
|
||||
|
||||
expectSuccess: false,
|
||||
outHolder: "bing",
|
||||
},
|
||||
{
|
||||
name: "don't acquire from led, acked new object, observe new record",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
|
||||
observedRawRecord: GetRawRecordOrDie(t, secondaryType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
|
||||
observedTime: future,
|
||||
|
||||
expectSuccess: false,
|
||||
outHolder: rl.UnknownLeader,
|
||||
},
|
||||
{
|
||||
name: "don't acquire from led, acked new object, observe transition record",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "bing"},
|
||||
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: "bing"}),
|
||||
observedTime: future,
|
||||
|
||||
expectSuccess: false,
|
||||
outHolder: "bing",
|
||||
},
|
||||
{
|
||||
name: "renew already required object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: primaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "get",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
objectType: secondaryType,
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, action.(fakeclient.UpdateAction).GetObject(), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
observedRecord: rl.LeaderElectionRecord{HolderIdentity: "baz"},
|
||||
observedRawRecord: GetRawRecordOrDie(t, objectType, rl.LeaderElectionRecord{HolderIdentity: "baz"}),
|
||||
observedTime: future,
|
||||
|
||||
expectSuccess: true,
|
||||
outHolder: "baz",
|
||||
},
|
||||
}
|
||||
|
||||
for i := range tests {
|
||||
test := &tests[i]
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
// OnNewLeader is called async so we have to wait for it.
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
var reportedLeader string
|
||||
var lock rl.Interface
|
||||
|
||||
objectMeta := metav1.ObjectMeta{Namespace: "foo", Name: "bar"}
|
||||
resourceLockConfig := rl.ResourceLockConfig{
|
||||
Identity: "baz",
|
||||
EventRecorder: &record.FakeRecorder{},
|
||||
}
|
||||
c := &fake.Clientset{}
|
||||
for _, reactor := range test.reactors {
|
||||
c.AddReactor(reactor.verb, reactor.objectType, reactor.reaction)
|
||||
}
|
||||
c.AddReactor("*", "*", func(action fakeclient.Action) (bool, runtime.Object, error) {
|
||||
t.Errorf("unreachable action. testclient called too many times: %+v", action)
|
||||
return true, nil, fmt.Errorf("unreachable action")
|
||||
})
|
||||
|
||||
switch objectType {
|
||||
case rl.EndpointsLeasesResourceLock:
|
||||
lock = &rl.MultiLock{
|
||||
Primary: &rl.EndpointsLock{
|
||||
EndpointsMeta: objectMeta,
|
||||
LockConfig: resourceLockConfig,
|
||||
Client: c.CoreV1(),
|
||||
},
|
||||
Secondary: &rl.LeaseLock{
|
||||
LeaseMeta: objectMeta,
|
||||
LockConfig: resourceLockConfig,
|
||||
Client: c.CoordinationV1(),
|
||||
},
|
||||
}
|
||||
case rl.ConfigMapsLeasesResourceLock:
|
||||
lock = &rl.MultiLock{
|
||||
Primary: &rl.ConfigMapLock{
|
||||
ConfigMapMeta: objectMeta,
|
||||
LockConfig: resourceLockConfig,
|
||||
Client: c.CoreV1(),
|
||||
},
|
||||
Secondary: &rl.LeaseLock{
|
||||
LeaseMeta: objectMeta,
|
||||
LockConfig: resourceLockConfig,
|
||||
Client: c.CoordinationV1(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
lec := LeaderElectionConfig{
|
||||
Lock: lock,
|
||||
LeaseDuration: 10 * time.Second,
|
||||
Callbacks: LeaderCallbacks{
|
||||
OnNewLeader: func(l string) {
|
||||
defer wg.Done()
|
||||
reportedLeader = l
|
||||
},
|
||||
},
|
||||
}
|
||||
le := &LeaderElector{
|
||||
config: lec,
|
||||
observedRecord: test.observedRecord,
|
||||
observedRawRecord: test.observedRawRecord,
|
||||
observedTime: test.observedTime,
|
||||
clock: clock.RealClock{},
|
||||
}
|
||||
if test.expectSuccess != le.tryAcquireOrRenew() {
|
||||
t.Errorf("unexpected result of tryAcquireOrRenew: [succeeded=%v]", !test.expectSuccess)
|
||||
}
|
||||
|
||||
le.observedRecord.AcquireTime = metav1.Time{}
|
||||
le.observedRecord.RenewTime = metav1.Time{}
|
||||
if le.observedRecord.HolderIdentity != test.outHolder {
|
||||
t.Errorf("expected holder:\n\t%+v\ngot:\n\t%+v", test.outHolder, le.observedRecord.HolderIdentity)
|
||||
}
|
||||
if len(test.reactors) != len(c.Actions()) {
|
||||
t.Errorf("wrong number of api interactions")
|
||||
}
|
||||
if test.transitionLeader && le.observedRecord.LeaderTransitions != 1 {
|
||||
t.Errorf("leader should have transitioned but did not")
|
||||
}
|
||||
if !test.transitionLeader && le.observedRecord.LeaderTransitions != 0 {
|
||||
t.Errorf("leader should not have transitioned but did")
|
||||
}
|
||||
|
||||
le.maybeReportTransition()
|
||||
wg.Wait()
|
||||
if reportedLeader != test.outHolder {
|
||||
t.Errorf("reported leader was not the new leader. expected %q, got %q", test.outHolder, reportedLeader)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Will test leader election using endpointsleases as the resource
|
||||
func TestTryAcquireOrRenewEndpointsLeases(t *testing.T) {
|
||||
testTryAcquireOrRenewMultiLock(t, "endpointsleases")
|
||||
}
|
||||
|
||||
// Will test leader election using configmapsleases as the resource
|
||||
func TestTryAcquireOrRenewConfigMapsLeases(t *testing.T) {
|
||||
testTryAcquireOrRenewMultiLock(t, "configmapsleases")
|
||||
}
|
||||
|
||||
@@ -41,22 +41,23 @@ type ConfigMapLock struct {
|
||||
}
|
||||
|
||||
// Get returns the election record from a ConfigMap Annotation
|
||||
func (cml *ConfigMapLock) Get() (*LeaderElectionRecord, error) {
|
||||
func (cml *ConfigMapLock) Get() (*LeaderElectionRecord, []byte, error) {
|
||||
var record LeaderElectionRecord
|
||||
var err error
|
||||
cml.cm, err = cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Get(cml.ConfigMapMeta.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
if cml.cm.Annotations == nil {
|
||||
cml.cm.Annotations = make(map[string]string)
|
||||
}
|
||||
if recordBytes, found := cml.cm.Annotations[LeaderElectionRecordAnnotationKey]; found {
|
||||
recordBytes, found := cml.cm.Annotations[LeaderElectionRecordAnnotationKey]
|
||||
if found {
|
||||
if err := json.Unmarshal([]byte(recordBytes), &record); err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
return &record, nil
|
||||
return &record, []byte(recordBytes), nil
|
||||
}
|
||||
|
||||
// Create attempts to create a LeaderElectionRecord annotation
|
||||
@@ -106,7 +107,7 @@ func (cml *ConfigMapLock) Describe() string {
|
||||
return fmt.Sprintf("%v/%v", cml.ConfigMapMeta.Namespace, cml.ConfigMapMeta.Name)
|
||||
}
|
||||
|
||||
// returns the Identity of the lock
|
||||
// Identity returns the Identity of the lock
|
||||
func (cml *ConfigMapLock) Identity() string {
|
||||
return cml.LockConfig.Identity
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user