mirror of
https://github.com/kubernetes/client-go.git
synced 2026-05-15 11:43:33 +00:00
Compare commits
78 Commits
release-1.
...
v0.17.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae93ed28af | ||
|
|
19522ff288 | ||
|
|
0cdd283dfd | ||
|
|
5ee463b7af | ||
|
|
b5eac8e744 | ||
|
|
7985654fe8 | ||
|
|
fa41b0c76b | ||
|
|
9f2f78dfcb | ||
|
|
27494d4fc8 | ||
|
|
62a43cf1f4 | ||
|
|
1b3201d12d | ||
|
|
61c8f156a0 | ||
|
|
6e35722da5 | ||
|
|
e3970fe37d | ||
|
|
3fe849aec4 | ||
|
|
3a262fe58a | ||
|
|
98f2fa70a1 | ||
|
|
e7b5e74ed4 | ||
|
|
d6c3975d42 | ||
|
|
cb7acd771d | ||
|
|
a4c677cde0 | ||
|
|
ce851c0bab | ||
|
|
e6529cdf92 | ||
|
|
e18bdbc334 | ||
|
|
f3cdcaf970 | ||
|
|
6e9b2dbbe2 | ||
|
|
7bd04c470b | ||
|
|
abd95e9c0a | ||
|
|
e5778855b5 | ||
|
|
eded95fdfd | ||
|
|
46af7b589b | ||
|
|
b761009965 | ||
|
|
a56e581315 | ||
|
|
bc842b510e | ||
|
|
83d8f38ea7 | ||
|
|
41d0b92a78 | ||
|
|
357aaec420 | ||
|
|
fed41f524f | ||
|
|
d78350395c | ||
|
|
af7d282afb | ||
|
|
7100912c84 | ||
|
|
9155fb5a6d | ||
|
|
43649d11a3 | ||
|
|
c7ba5618fd | ||
|
|
f1f7f7d673 | ||
|
|
fcde0a10c8 | ||
|
|
8d80aca827 | ||
|
|
14c92e3dc9 | ||
|
|
4ad43eb493 | ||
|
|
902f3aa269 | ||
|
|
c22145c02d | ||
|
|
4fb1ca18ca | ||
|
|
e706f8232c | ||
|
|
7e3bd58445 | ||
|
|
e0e2ffb8d0 | ||
|
|
5fc7a9e1ae | ||
|
|
eaf5bb0b36 | ||
|
|
86bac3ac1a | ||
|
|
00967f30df | ||
|
|
b132d4e8c2 | ||
|
|
100eed2f5c | ||
|
|
737b0684f7 | ||
|
|
7579be31b1 | ||
|
|
1e021533f5 | ||
|
|
60db0a7b4e | ||
|
|
d26f3bbd8a | ||
|
|
20cbac8786 | ||
|
|
7727ca7e78 | ||
|
|
15d0792143 | ||
|
|
64d0d9280f | ||
|
|
e58f47ad45 | ||
|
|
dc0ddc68f2 | ||
|
|
678d0436c4 | ||
|
|
4b3ee58116 | ||
|
|
f7396e6e2b | ||
|
|
1706989ec7 | ||
|
|
2225ff19d9 | ||
|
|
346cddd7c2 |
42
Godeps/Godeps.json
generated
42
Godeps/Godeps.json
generated
@@ -164,7 +164,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gregjones/httpcache",
|
||||
"Rev": "787624de3eb7"
|
||||
"Rev": "9cad4c3443a7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/golang-lru",
|
||||
@@ -180,7 +180,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/json-iterator/go",
|
||||
"Rev": "v1.1.7"
|
||||
"Rev": "v1.1.8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jstemmer/go-junit-report",
|
||||
@@ -248,7 +248,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/pflag",
|
||||
"Rev": "v1.0.3"
|
||||
"Rev": "v1.0.5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/objx",
|
||||
@@ -256,7 +256,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/testify",
|
||||
"Rev": "v1.3.0"
|
||||
"Rev": "v1.4.0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "go.opencensus.io",
|
||||
@@ -264,7 +264,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto",
|
||||
"Rev": "e84da0312774"
|
||||
"Rev": "60c769a6c586"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/exp",
|
||||
@@ -272,35 +272,39 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/lint",
|
||||
"Rev": "8f45f776aaf1"
|
||||
"Rev": "5614ed5bae6f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net",
|
||||
"Rev": "cdfb69ac37fc"
|
||||
"Rev": "13f9640d40b9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2",
|
||||
"Rev": "9f3314589c9a"
|
||||
"Rev": "0f29369cfe45"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/sync",
|
||||
"Rev": "42b317875d0f"
|
||||
"Rev": "112230192c58"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/sys",
|
||||
"Rev": "3b5209105503"
|
||||
"Rev": "fde4db37ae7a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text",
|
||||
"Rev": "e6919f6577db"
|
||||
"Rev": "v0.3.2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/time",
|
||||
"Rev": "f51c12702a4d"
|
||||
"Rev": "9d24e82272b4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/tools",
|
||||
"Rev": "e65039ee4138"
|
||||
"Rev": "65e3620a7ae7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/xerrors",
|
||||
"Rev": "a985d3407aa7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api",
|
||||
@@ -328,7 +332,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/inf.v0",
|
||||
"Rev": "v0.9.0"
|
||||
"Rev": "v0.9.1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/tomb.v1",
|
||||
@@ -336,7 +340,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/yaml.v2",
|
||||
"Rev": "v2.2.4"
|
||||
"Rev": "v2.2.8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "honnef.co/go/tools",
|
||||
@@ -344,11 +348,11 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api",
|
||||
"Rev": "5524a3672fbb"
|
||||
"Rev": "v0.17.3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery",
|
||||
"Rev": "af6325b3a843"
|
||||
"Rev": "v0.17.3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo",
|
||||
@@ -360,11 +364,11 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi",
|
||||
"Rev": "743ec37842bf"
|
||||
"Rev": "30be4d16710a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/utils",
|
||||
"Rev": "8d271d903fe4"
|
||||
"Rev": "e782cd3c129f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "sigs.k8s.io/structured-merge-diff",
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 dynamic provides a client interface to arbitrary Kubernetes
|
||||
// APIs that exposes common high level operations and exposes common
|
||||
// metadata.
|
||||
package deprecated_dynamic
|
||||
|
||||
import (
|
||||
"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/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/dynamic"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// Interface is a Kubernetes client that allows you to access metadata
|
||||
// and manipulate metadata of a Kubernetes API group.
|
||||
type Interface interface {
|
||||
// Resource returns an API interface to the specified resource for this client's
|
||||
// group and version. If resource is not a namespaced resource, then namespace
|
||||
// is ignored. The ResourceInterface inherits the parameter codec of this client.
|
||||
Resource(resource *metav1.APIResource, namespace string) ResourceInterface
|
||||
}
|
||||
|
||||
// ResourceInterface is an API interface to a specific resource under a
|
||||
// dynamic client.
|
||||
type ResourceInterface interface {
|
||||
// List returns a list of objects for this resource.
|
||||
List(opts metav1.ListOptions) (runtime.Object, error)
|
||||
// Get gets the resource with the specified name.
|
||||
Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error)
|
||||
// Delete deletes the resource with the specified name.
|
||||
Delete(name string, opts *metav1.DeleteOptions) error
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error
|
||||
// Create creates the provided resource.
|
||||
Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
||||
// Update updates the provided resource.
|
||||
Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
||||
// Watch returns a watch.Interface that watches the resource.
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
// Patch patches the provided resource.
|
||||
Patch(name string, pt types.PatchType, data []byte) (*unstructured.Unstructured, error)
|
||||
}
|
||||
|
||||
// Client is a Kubernetes client that allows you to access metadata
|
||||
// and manipulate metadata of a Kubernetes API group, and implements Interface.
|
||||
type Client struct {
|
||||
version schema.GroupVersion
|
||||
delegate dynamic.Interface
|
||||
}
|
||||
|
||||
// NewClient returns a new client based on the passed in config. The
|
||||
// codec is ignored, as the dynamic client uses it's own codec.
|
||||
func NewClient(conf *restclient.Config, version schema.GroupVersion) (*Client, error) {
|
||||
delegate, err := dynamic.NewForConfig(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{version: version, delegate: delegate}, nil
|
||||
}
|
||||
|
||||
// Resource returns an API interface to the specified resource for this client's
|
||||
// group and version. If resource is not a namespaced resource, then namespace
|
||||
// is ignored. The ResourceInterface inherits the parameter codec of c.
|
||||
func (c *Client) Resource(resource *metav1.APIResource, namespace string) ResourceInterface {
|
||||
resourceTokens := strings.SplitN(resource.Name, "/", 2)
|
||||
subresources := []string{}
|
||||
if len(resourceTokens) > 1 {
|
||||
subresources = strings.Split(resourceTokens[1], "/")
|
||||
}
|
||||
|
||||
if len(namespace) == 0 {
|
||||
return oldResourceShim(c.delegate.Resource(c.version.WithResource(resourceTokens[0])), subresources)
|
||||
}
|
||||
return oldResourceShim(c.delegate.Resource(c.version.WithResource(resourceTokens[0])).Namespace(namespace), subresources)
|
||||
}
|
||||
|
||||
// the old interfaces used the wrong type for lists. this fixes that
|
||||
func oldResourceShim(in dynamic.ResourceInterface, subresources []string) ResourceInterface {
|
||||
return oldResourceShimType{ResourceInterface: in, subresources: subresources}
|
||||
}
|
||||
|
||||
type oldResourceShimType struct {
|
||||
dynamic.ResourceInterface
|
||||
subresources []string
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
return s.ResourceInterface.Create(obj, metav1.CreateOptions{}, s.subresources...)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
return s.ResourceInterface.Update(obj, metav1.UpdateOptions{}, s.subresources...)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return s.ResourceInterface.Delete(name, opts, s.subresources...)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
|
||||
return s.ResourceInterface.Get(name, opts, s.subresources...)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) List(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
return s.ResourceInterface.List(opts)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Patch(name string, pt types.PatchType, data []byte) (*unstructured.Unstructured, error) {
|
||||
return s.ResourceInterface.Patch(name, pt, data, metav1.PatchOptions{}, s.subresources...)
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 (
|
||||
"sync"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// ClientPool manages a pool of dynamic clients.
|
||||
type ClientPool interface {
|
||||
// ClientForGroupVersionResource returns a client configured for the specified groupVersionResource.
|
||||
// Resource may be empty.
|
||||
ClientForGroupVersionResource(resource schema.GroupVersionResource) (Interface, error)
|
||||
// ClientForGroupVersionKind returns a client configured for the specified groupVersionKind.
|
||||
// Kind may be empty.
|
||||
ClientForGroupVersionKind(kind schema.GroupVersionKind) (Interface, error)
|
||||
}
|
||||
|
||||
// APIPathResolverFunc knows how to convert a groupVersion to its API path. The Kind field is
|
||||
// optional.
|
||||
type APIPathResolverFunc func(kind schema.GroupVersionKind) string
|
||||
|
||||
// LegacyAPIPathResolverFunc can resolve paths properly with the legacy API.
|
||||
func LegacyAPIPathResolverFunc(kind schema.GroupVersionKind) string {
|
||||
if len(kind.Group) == 0 {
|
||||
return "/api"
|
||||
}
|
||||
return "/apis"
|
||||
}
|
||||
|
||||
// clientPoolImpl implements ClientPool and caches clients for the resource group versions
|
||||
// is asked to retrieve. This type is thread safe.
|
||||
type clientPoolImpl struct {
|
||||
lock sync.RWMutex
|
||||
config *restclient.Config
|
||||
clients map[schema.GroupVersion]*Client
|
||||
apiPathResolverFunc APIPathResolverFunc
|
||||
mapper meta.RESTMapper
|
||||
}
|
||||
|
||||
// NewClientPool returns a ClientPool from the specified config. It reuses clients for the same
|
||||
// group version. It is expected this type may be wrapped by specific logic that special cases certain
|
||||
// resources or groups.
|
||||
func NewClientPool(config *restclient.Config, mapper meta.RESTMapper, apiPathResolverFunc APIPathResolverFunc) ClientPool {
|
||||
confCopy := *config
|
||||
|
||||
return &clientPoolImpl{
|
||||
config: &confCopy,
|
||||
clients: map[schema.GroupVersion]*Client{},
|
||||
apiPathResolverFunc: apiPathResolverFunc,
|
||||
mapper: mapper,
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiates a new dynamic client pool with the given config.
|
||||
func NewDynamicClientPool(cfg *restclient.Config) ClientPool {
|
||||
// restMapper is not needed when using LegacyAPIPathResolverFunc
|
||||
emptyMapper := meta.MultiRESTMapper{}
|
||||
return NewClientPool(cfg, emptyMapper, LegacyAPIPathResolverFunc)
|
||||
}
|
||||
|
||||
// ClientForGroupVersionResource uses the provided RESTMapper to identify the appropriate resource. Resource may
|
||||
// be empty. If no matching kind is found the underlying client for that group is still returned.
|
||||
func (c *clientPoolImpl) ClientForGroupVersionResource(resource schema.GroupVersionResource) (Interface, error) {
|
||||
kinds, err := c.mapper.KindsFor(resource)
|
||||
if err != nil {
|
||||
if meta.IsNoMatchError(err) {
|
||||
return c.ClientForGroupVersionKind(schema.GroupVersionKind{Group: resource.Group, Version: resource.Version})
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return c.ClientForGroupVersionKind(kinds[0])
|
||||
}
|
||||
|
||||
// ClientForGroupVersion returns a client for the specified groupVersion, creates one if none exists. Kind
|
||||
// in the GroupVersionKind may be empty.
|
||||
func (c *clientPoolImpl) ClientForGroupVersionKind(kind schema.GroupVersionKind) (Interface, error) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
gv := kind.GroupVersion()
|
||||
|
||||
// do we have a client already configured?
|
||||
if existingClient, found := c.clients[gv]; found {
|
||||
return existingClient, nil
|
||||
}
|
||||
|
||||
// avoid changing the original config
|
||||
confCopy := *c.config
|
||||
conf := &confCopy
|
||||
|
||||
// we need to set the api path based on group version, if no group, default to legacy path
|
||||
conf.APIPath = c.apiPathResolverFunc(kind)
|
||||
|
||||
// we need to make a client
|
||||
conf.GroupVersion = &gv
|
||||
|
||||
dynamicClient, err := NewClient(conf, gv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.clients[gv] = dynamicClient
|
||||
return dynamicClient, nil
|
||||
}
|
||||
@@ -1,624 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
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/streaming"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
restclientwatch "k8s.io/client-go/rest/watch"
|
||||
)
|
||||
|
||||
func getJSON(version, kind, name string) []byte {
|
||||
return []byte(fmt.Sprintf(`{"apiVersion": %q, "kind": %q, "metadata": {"name": %q}}`, version, kind, name))
|
||||
}
|
||||
|
||||
func getListJSON(version, kind string, items ...[]byte) []byte {
|
||||
json := fmt.Sprintf(`{"apiVersion": %q, "kind": %q, "items": [%s]}`,
|
||||
version, kind, bytes.Join(items, []byte(",")))
|
||||
return []byte(json)
|
||||
}
|
||||
|
||||
func getObject(version, kind, name string) *unstructured.Unstructured {
|
||||
return &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": version,
|
||||
"kind": kind,
|
||||
"metadata": map[string]interface{}{
|
||||
"name": name,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getClientServer(gv *schema.GroupVersion, h func(http.ResponseWriter, *http.Request)) (Interface, *httptest.Server, error) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(h))
|
||||
cl, err := NewClient(&restclient.Config{
|
||||
Host: srv.URL,
|
||||
ContentConfig: restclient.ContentConfig{GroupVersion: gv},
|
||||
}, *gv)
|
||||
if err != nil {
|
||||
srv.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
return cl, srv, nil
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
namespace string
|
||||
path string
|
||||
resp []byte
|
||||
want *unstructured.UnstructuredList
|
||||
}{
|
||||
{
|
||||
name: "normal_list",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
resp: getListJSON("vTest", "rTestList",
|
||||
getJSON("vTest", "rTest", "item1"),
|
||||
getJSON("vTest", "rTest", "item2")),
|
||||
want: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "vTest",
|
||||
"kind": "rTestList",
|
||||
},
|
||||
Items: []unstructured.Unstructured{
|
||||
*getObject("vTest", "rTest", "item1"),
|
||||
*getObject("vTest", "rTest", "item2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "namespaced_list",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
resp: getListJSON("vTest", "rTestList",
|
||||
getJSON("vTest", "rTest", "item1"),
|
||||
getJSON("vTest", "rTest", "item2")),
|
||||
want: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "vTest",
|
||||
"kind": "rTestList",
|
||||
},
|
||||
Items: []unstructured.Unstructured{
|
||||
*getObject("vTest", "rTest", "item1"),
|
||||
*getObject("vTest", "rTest", "item2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("List(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("List(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
w.Write(tc.resp)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when listing %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("List(%q) want: %v\ngot: %v", tc.name, tc.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
resp []byte
|
||||
want *unstructured.Unstructured
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_get",
|
||||
path: "/apis/gtest/vtest/rtest/normal_get",
|
||||
resp: getJSON("vTest", "rTest", "normal_get"),
|
||||
want: getObject("vTest", "rTest", "normal_get"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
namespace: "nstest",
|
||||
name: "namespaced_get",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_get",
|
||||
resp: getJSON("vTest", "rTest", "namespaced_get"),
|
||||
want: getObject("vTest", "rTest", "namespaced_get"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_get",
|
||||
path: "/apis/gtest/vtest/rtest/normal_subresource_get/srtest",
|
||||
resp: getJSON("vTest", "srTest", "normal_subresource_get"),
|
||||
want: getObject("vTest", "srTest", "normal_subresource_get"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
namespace: "nstest",
|
||||
name: "namespaced_subresource_get",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_get/srtest",
|
||||
resp: getJSON("vTest", "srTest", "namespaced_subresource_get"),
|
||||
want: getObject("vTest", "srTest", "namespaced_subresource_get"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("Get(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Get(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
w.Write(tc.resp)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).Get(tc.name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when getting %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("Get(%q) want: %v\ngot: %v", tc.name, tc.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
background := metav1.DeletePropagationBackground
|
||||
uid := types.UID("uid")
|
||||
|
||||
statusOK := &metav1.Status{
|
||||
TypeMeta: metav1.TypeMeta{Kind: "Status"},
|
||||
Status: metav1.StatusSuccess,
|
||||
}
|
||||
tcs := []struct {
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
deleteOptions *metav1.DeleteOptions
|
||||
}{
|
||||
{
|
||||
name: "normal_delete",
|
||||
path: "/apis/gtest/vtest/rtest/normal_delete",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete_with_options",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete_with_options",
|
||||
deleteOptions: &metav1.DeleteOptions{Preconditions: &metav1.Preconditions{UID: &uid}, PropagationPolicy: &background},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "DELETE" {
|
||||
t.Errorf("Delete(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Delete(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
unstructured.UnstructuredJSONScheme.Encode(statusOK, w)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
err = cl.Resource(resource, tc.namespace).Delete(tc.name, tc.deleteOptions)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when deleting %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteCollection(t *testing.T) {
|
||||
statusOK := &metav1.Status{
|
||||
TypeMeta: metav1.TypeMeta{Kind: "Status"},
|
||||
Status: metav1.StatusSuccess,
|
||||
}
|
||||
tcs := []struct {
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
}{
|
||||
{
|
||||
name: "normal_delete_collection",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete_collection",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "DELETE" {
|
||||
t.Errorf("DeleteCollection(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("DeleteCollection(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
unstructured.UnstructuredJSONScheme.Encode(statusOK, w)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
err = cl.Resource(resource, tc.namespace).DeleteCollection(nil, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when deleting collection %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
obj *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_create",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
obj: getObject("gtest/vTest", "rTest", "normal_create"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_create",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
obj: getObject("gtest/vTest", "rTest", "namespaced_create"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
t.Errorf("Create(%q) got HTTP method %s. wanted POST", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Create(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Create(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(data)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).Create(tc.obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.obj) {
|
||||
t.Errorf("Create(%q) want: %v\ngot: %v", tc.name, tc.obj, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
obj *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_update",
|
||||
path: "/apis/gtest/vtest/rtest/normal_update",
|
||||
obj: getObject("gtest/vTest", "rTest", "normal_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_update",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_update",
|
||||
obj: getObject("gtest/vTest", "rTest", "namespaced_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_update",
|
||||
path: "/apis/gtest/vtest/rtest/normal_update/srtest",
|
||||
obj: getObject("gtest/vTest", "srTest", "normal_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "namespaced_subresource_update",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_update/srtest",
|
||||
obj: getObject("gtest/vTest", "srTest", "namespaced_update"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "PUT" {
|
||||
t.Errorf("Update(%q) got HTTP method %s. wanted PUT", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Update(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Update(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(data)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).Update(tc.obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when updating %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.obj) {
|
||||
t.Errorf("Update(%q) want: %v\ngot: %v", tc.name, tc.obj, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
namespace string
|
||||
events []watch.Event
|
||||
path string
|
||||
query string
|
||||
}{
|
||||
{
|
||||
name: "normal_watch",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
query: "watch=true",
|
||||
events: []watch.Event{
|
||||
{Type: watch.Added, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Modified, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Deleted, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "namespaced_watch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
query: "watch=true",
|
||||
events: []watch.Event{
|
||||
{Type: watch.Added, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Modified, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Deleted, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("Watch(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Watch(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
if r.URL.RawQuery != tc.query {
|
||||
t.Errorf("Watch(%q) got query %s. wanted %s", tc.name, r.URL.RawQuery, tc.query)
|
||||
}
|
||||
|
||||
codec := unstructured.UnstructuredJSONScheme
|
||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, codec), codec)
|
||||
for _, e := range tc.events {
|
||||
enc.Encode(&e)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
watcher, err := cl.Resource(resource, tc.namespace).Watch(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when watching %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, want := range tc.events {
|
||||
got := <-watcher.ResultChan()
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("Watch(%q) want: %v\ngot: %v", tc.name, want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatch(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
patch []byte
|
||||
want *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_patch",
|
||||
path: "/apis/gtest/vtest/rtest/normal_patch",
|
||||
patch: getJSON("gtest/vTest", "rTest", "normal_patch"),
|
||||
want: getObject("gtest/vTest", "rTest", "normal_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_patch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_patch",
|
||||
patch: getJSON("gtest/vTest", "rTest", "namespaced_patch"),
|
||||
want: getObject("gtest/vTest", "rTest", "namespaced_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_patch",
|
||||
path: "/apis/gtest/vtest/rtest/normal_subresource_patch/srtest",
|
||||
patch: getJSON("gtest/vTest", "srTest", "normal_subresource_patch"),
|
||||
want: getObject("gtest/vTest", "srTest", "normal_subresource_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "namespaced_subresource_patch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_patch/srtest",
|
||||
patch: getJSON("gtest/vTest", "srTest", "namespaced_subresource_patch"),
|
||||
want: getObject("gtest/vTest", "srTest", "namespaced_subresource_patch"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "PATCH" {
|
||||
t.Errorf("Patch(%q) got HTTP method %s. wanted PATCH", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Patch(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
content := r.Header.Get("Content-Type")
|
||||
if content != string(types.StrategicMergePatchType) {
|
||||
t.Errorf("Patch(%q) got Content-Type %s. wanted %s", tc.name, content, types.StrategicMergePatchType)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Patch(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(data)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).Patch(tc.name, types.StrategicMergePatchType, tc.patch)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when patching %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("Patch(%q) want: %v\ngot: %v", tc.name, tc.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -463,6 +463,13 @@ func setDiscoveryDefaults(config *restclient.Config) error {
|
||||
if config.Timeout == 0 {
|
||||
config.Timeout = defaultTimeout
|
||||
}
|
||||
if config.Burst == 0 && config.QPS < 100 {
|
||||
// discovery is expected to be bursty, increase the default burst
|
||||
// to accommodate looking up resource info for many API groups.
|
||||
// matches burst set by ConfigFlags#ToDiscoveryClient().
|
||||
// see https://issue.k8s.io/86149
|
||||
config.Burst = 100
|
||||
}
|
||||
codec := runtime.NoopEncoder{Decoder: scheme.Codecs.UniversalDecoder()}
|
||||
config.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec})
|
||||
if len(config.UserAgent) == 0 {
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/googleapis/gnostic/OpenAPIv2"
|
||||
@@ -198,6 +199,26 @@ func TestGetServerResources(t *testing.T) {
|
||||
{Name: "jobs", Namespaced: true, Kind: "Job"},
|
||||
},
|
||||
}
|
||||
extensionsbeta3 := metav1.APIResourceList{GroupVersion: "extensions/v1beta3", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
extensionsbeta4 := metav1.APIResourceList{GroupVersion: "extensions/v1beta4", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
extensionsbeta5 := metav1.APIResourceList{GroupVersion: "extensions/v1beta5", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
extensionsbeta6 := metav1.APIResourceList{GroupVersion: "extensions/v1beta6", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
extensionsbeta7 := metav1.APIResourceList{GroupVersion: "extensions/v1beta7", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
extensionsbeta8 := metav1.APIResourceList{GroupVersion: "extensions/v1beta8", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
extensionsbeta9 := metav1.APIResourceList{GroupVersion: "extensions/v1beta9", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
extensionsbeta10 := metav1.APIResourceList{GroupVersion: "extensions/v1beta10", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
|
||||
appsbeta1 := metav1.APIResourceList{GroupVersion: "apps/v1beta1", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta2 := metav1.APIResourceList{GroupVersion: "apps/v1beta2", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta3 := metav1.APIResourceList{GroupVersion: "apps/v1beta3", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta4 := metav1.APIResourceList{GroupVersion: "apps/v1beta4", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta5 := metav1.APIResourceList{GroupVersion: "apps/v1beta5", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta6 := metav1.APIResourceList{GroupVersion: "apps/v1beta6", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta7 := metav1.APIResourceList{GroupVersion: "apps/v1beta7", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta8 := metav1.APIResourceList{GroupVersion: "apps/v1beta8", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta9 := metav1.APIResourceList{GroupVersion: "apps/v1beta9", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
appsbeta10 := metav1.APIResourceList{GroupVersion: "apps/v1beta10", APIResources: []metav1.APIResource{{Name: "deployments", Namespaced: true, Kind: "Deployment"}}}
|
||||
|
||||
tests := []struct {
|
||||
resourcesList *metav1.APIResourceList
|
||||
path string
|
||||
@@ -232,6 +253,42 @@ func TestGetServerResources(t *testing.T) {
|
||||
list = &beta
|
||||
case "/apis/extensions/v1beta2":
|
||||
list = &beta2
|
||||
case "/apis/extensions/v1beta3":
|
||||
list = &extensionsbeta3
|
||||
case "/apis/extensions/v1beta4":
|
||||
list = &extensionsbeta4
|
||||
case "/apis/extensions/v1beta5":
|
||||
list = &extensionsbeta5
|
||||
case "/apis/extensions/v1beta6":
|
||||
list = &extensionsbeta6
|
||||
case "/apis/extensions/v1beta7":
|
||||
list = &extensionsbeta7
|
||||
case "/apis/extensions/v1beta8":
|
||||
list = &extensionsbeta8
|
||||
case "/apis/extensions/v1beta9":
|
||||
list = &extensionsbeta9
|
||||
case "/apis/extensions/v1beta10":
|
||||
list = &extensionsbeta10
|
||||
case "/apis/apps/v1beta1":
|
||||
list = &appsbeta1
|
||||
case "/apis/apps/v1beta2":
|
||||
list = &appsbeta2
|
||||
case "/apis/apps/v1beta3":
|
||||
list = &appsbeta3
|
||||
case "/apis/apps/v1beta4":
|
||||
list = &appsbeta4
|
||||
case "/apis/apps/v1beta5":
|
||||
list = &appsbeta5
|
||||
case "/apis/apps/v1beta6":
|
||||
list = &appsbeta6
|
||||
case "/apis/apps/v1beta7":
|
||||
list = &appsbeta7
|
||||
case "/apis/apps/v1beta8":
|
||||
list = &appsbeta8
|
||||
case "/apis/apps/v1beta9":
|
||||
list = &appsbeta9
|
||||
case "/apis/apps/v1beta10":
|
||||
list = &appsbeta10
|
||||
case "/api":
|
||||
list = &metav1.APIVersions{
|
||||
Versions: []string{
|
||||
@@ -241,11 +298,34 @@ func TestGetServerResources(t *testing.T) {
|
||||
case "/apis":
|
||||
list = &metav1.APIGroupList{
|
||||
Groups: []metav1.APIGroup{
|
||||
{
|
||||
Name: "apps",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{GroupVersion: "apps/v1beta1", Version: "v1beta1"},
|
||||
{GroupVersion: "apps/v1beta2", Version: "v1beta2"},
|
||||
{GroupVersion: "apps/v1beta3", Version: "v1beta3"},
|
||||
{GroupVersion: "apps/v1beta4", Version: "v1beta4"},
|
||||
{GroupVersion: "apps/v1beta5", Version: "v1beta5"},
|
||||
{GroupVersion: "apps/v1beta6", Version: "v1beta6"},
|
||||
{GroupVersion: "apps/v1beta7", Version: "v1beta7"},
|
||||
{GroupVersion: "apps/v1beta8", Version: "v1beta8"},
|
||||
{GroupVersion: "apps/v1beta9", Version: "v1beta9"},
|
||||
{GroupVersion: "apps/v1beta10", Version: "v1beta10"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "extensions",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{GroupVersion: "extensions/v1beta1", Version: "v1beta1"},
|
||||
{GroupVersion: "extensions/v1beta2", Version: "v1beta2"},
|
||||
{GroupVersion: "extensions/v1beta3", Version: "v1beta3"},
|
||||
{GroupVersion: "extensions/v1beta4", Version: "v1beta4"},
|
||||
{GroupVersion: "extensions/v1beta5", Version: "v1beta5"},
|
||||
{GroupVersion: "extensions/v1beta6", Version: "v1beta6"},
|
||||
{GroupVersion: "extensions/v1beta7", Version: "v1beta7"},
|
||||
{GroupVersion: "extensions/v1beta8", Version: "v1beta8"},
|
||||
{GroupVersion: "extensions/v1beta9", Version: "v1beta9"},
|
||||
{GroupVersion: "extensions/v1beta10", Version: "v1beta10"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -265,8 +345,8 @@ func TestGetServerResources(t *testing.T) {
|
||||
w.Write(output)
|
||||
}))
|
||||
defer server.Close()
|
||||
client := NewDiscoveryClientForConfigOrDie(&restclient.Config{Host: server.URL})
|
||||
for _, test := range tests {
|
||||
client := NewDiscoveryClientForConfigOrDie(&restclient.Config{Host: server.URL})
|
||||
got, err := client.ServerResourcesForGroupVersion(test.request)
|
||||
if test.expectErr {
|
||||
if err == nil {
|
||||
@@ -283,12 +363,40 @@ func TestGetServerResources(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
client := NewDiscoveryClientForConfigOrDie(&restclient.Config{Host: server.URL})
|
||||
start := time.Now()
|
||||
serverResources, err := client.ServerResources()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
end := time.Now()
|
||||
if d := end.Sub(start); d > time.Second {
|
||||
t.Errorf("took too long to perform discovery: %s", d)
|
||||
}
|
||||
serverGroupVersions := groupVersions(serverResources)
|
||||
expectedGroupVersions := []string{"v1", "extensions/v1beta1", "extensions/v1beta2"}
|
||||
expectedGroupVersions := []string{
|
||||
"v1",
|
||||
"apps/v1beta1",
|
||||
"apps/v1beta2",
|
||||
"apps/v1beta3",
|
||||
"apps/v1beta4",
|
||||
"apps/v1beta5",
|
||||
"apps/v1beta6",
|
||||
"apps/v1beta7",
|
||||
"apps/v1beta8",
|
||||
"apps/v1beta9",
|
||||
"apps/v1beta10",
|
||||
"extensions/v1beta1",
|
||||
"extensions/v1beta2",
|
||||
"extensions/v1beta3",
|
||||
"extensions/v1beta4",
|
||||
"extensions/v1beta5",
|
||||
"extensions/v1beta6",
|
||||
"extensions/v1beta7",
|
||||
"extensions/v1beta8",
|
||||
"extensions/v1beta9",
|
||||
"extensions/v1beta10",
|
||||
}
|
||||
if !reflect.DeepEqual(expectedGroupVersions, serverGroupVersions) {
|
||||
t.Errorf("unexpected group versions: %v", diff.ObjectReflectDiff(expectedGroupVersions, serverGroupVersions))
|
||||
}
|
||||
|
||||
@@ -537,6 +537,8 @@ func TestWatch(t *testing.T) {
|
||||
t.Errorf("Watch(%q) got query %s. wanted %s", tc.name, r.URL.RawQuery, tc.query)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, unstructured.UnstructuredJSONScheme), unstructured.UnstructuredJSONScheme)
|
||||
for _, e := range tc.events {
|
||||
enc.Encode(&e)
|
||||
|
||||
@@ -18,11 +18,11 @@ package dynamic
|
||||
|
||||
import (
|
||||
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/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
|
||||
)
|
||||
|
||||
var watchScheme = runtime.NewScheme()
|
||||
@@ -41,37 +41,6 @@ func init() {
|
||||
metav1.AddToGroupVersion(deleteScheme, versionV1)
|
||||
}
|
||||
|
||||
var watchJsonSerializerInfo = runtime.SerializerInfo{
|
||||
MediaType: "application/json",
|
||||
MediaTypeType: "application",
|
||||
MediaTypeSubType: "json",
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, watchScheme, watchScheme, false),
|
||||
PrettySerializer: json.NewSerializer(json.DefaultMetaFactory, watchScheme, watchScheme, true),
|
||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, watchScheme, watchScheme, false),
|
||||
Framer: json.Framer,
|
||||
},
|
||||
}
|
||||
|
||||
// watchNegotiatedSerializer is used to read the wrapper of the watch stream
|
||||
type watchNegotiatedSerializer struct{}
|
||||
|
||||
var watchNegotiatedSerializerInstance = watchNegotiatedSerializer{}
|
||||
|
||||
func (s watchNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
|
||||
return []runtime.SerializerInfo{watchJsonSerializerInfo}
|
||||
}
|
||||
|
||||
func (s watchNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
|
||||
return versioning.NewDefaultingCodecForScheme(watchScheme, encoder, nil, gv, nil)
|
||||
}
|
||||
|
||||
func (s watchNegotiatedSerializer) DecoderToVersion(decoder runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder {
|
||||
return versioning.NewDefaultingCodecForScheme(watchScheme, nil, decoder, nil, gv)
|
||||
}
|
||||
|
||||
// basicNegotiatedSerializer is used to handle discovery and error handling serialization
|
||||
type basicNegotiatedSerializer struct{}
|
||||
|
||||
@@ -82,8 +51,8 @@ func (s basicNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInf
|
||||
MediaTypeType: "application",
|
||||
MediaTypeSubType: "json",
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, basicScheme, basicScheme, false),
|
||||
PrettySerializer: json.NewSerializer(json.DefaultMetaFactory, basicScheme, basicScheme, true),
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, unstructuredCreater{basicScheme}, unstructuredTyper{basicScheme}, false),
|
||||
PrettySerializer: json.NewSerializer(json.DefaultMetaFactory, unstructuredCreater{basicScheme}, unstructuredTyper{basicScheme}, true),
|
||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, basicScheme, basicScheme, false),
|
||||
@@ -94,9 +63,46 @@ func (s basicNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInf
|
||||
}
|
||||
|
||||
func (s basicNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
|
||||
return versioning.NewDefaultingCodecForScheme(watchScheme, encoder, nil, gv, nil)
|
||||
return runtime.WithVersionEncoder{
|
||||
Version: gv,
|
||||
Encoder: encoder,
|
||||
ObjectTyper: unstructuredTyper{basicScheme},
|
||||
}
|
||||
}
|
||||
|
||||
func (s basicNegotiatedSerializer) DecoderToVersion(decoder runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder {
|
||||
return versioning.NewDefaultingCodecForScheme(watchScheme, nil, decoder, nil, gv)
|
||||
return decoder
|
||||
}
|
||||
|
||||
type unstructuredCreater struct {
|
||||
nested runtime.ObjectCreater
|
||||
}
|
||||
|
||||
func (c unstructuredCreater) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
||||
out, err := c.nested.New(kind)
|
||||
if err == nil {
|
||||
return out, nil
|
||||
}
|
||||
out = &unstructured.Unstructured{}
|
||||
out.GetObjectKind().SetGroupVersionKind(kind)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
type unstructuredTyper struct {
|
||||
nested runtime.ObjectTyper
|
||||
}
|
||||
|
||||
func (t unstructuredTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
kinds, unversioned, err := t.nested.ObjectKinds(obj)
|
||||
if err == nil {
|
||||
return kinds, unversioned, nil
|
||||
}
|
||||
if _, ok := obj.(runtime.Unstructured); ok && !obj.GetObjectKind().GroupVersionKind().Empty() {
|
||||
return []schema.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
func (t unstructuredTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -18,14 +18,12 @@ package dynamic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"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/runtime/serializer/streaming"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/rest"
|
||||
@@ -282,31 +280,10 @@ func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.Uns
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
internalGV := schema.GroupVersions{
|
||||
{Group: c.resource.Group, Version: runtime.APIVersionInternal},
|
||||
// always include the legacy group as a decoding target to handle non-error `Status` return types
|
||||
{Group: "", Version: runtime.APIVersionInternal},
|
||||
}
|
||||
s := &rest.Serializers{
|
||||
Encoder: watchNegotiatedSerializerInstance.EncoderForVersion(watchJsonSerializerInfo.Serializer, c.resource.GroupVersion()),
|
||||
Decoder: watchNegotiatedSerializerInstance.DecoderToVersion(watchJsonSerializerInfo.Serializer, internalGV),
|
||||
|
||||
RenegotiatedDecoder: func(contentType string, params map[string]string) (runtime.Decoder, error) {
|
||||
return watchNegotiatedSerializerInstance.DecoderToVersion(watchJsonSerializerInfo.Serializer, internalGV), nil
|
||||
},
|
||||
StreamingSerializer: watchJsonSerializerInfo.StreamSerializer.Serializer,
|
||||
Framer: watchJsonSerializerInfo.StreamSerializer.Framer,
|
||||
}
|
||||
|
||||
wrappedDecoderFn := func(body io.ReadCloser) streaming.Decoder {
|
||||
framer := s.Framer.NewFrameReader(body)
|
||||
return streaming.NewDecoder(framer, s.StreamingSerializer)
|
||||
}
|
||||
|
||||
opts.Watch = true
|
||||
return c.client.client.Get().AbsPath(c.makeURLSegments("")...).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
WatchWithSpecificDecoders(wrappedDecoderFn, unstructured.UnstructuredJSONScheme)
|
||||
Watch()
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Patch(name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
|
||||
32
go.mod
32
go.mod
@@ -18,32 +18,26 @@ require (
|
||||
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
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7
|
||||
github.com/imdario/mergo v0.3.5
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible
|
||||
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-20190813141303-74dc4d7220e7
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.4.0
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
|
||||
google.golang.org/appengine v1.5.0 // indirect
|
||||
k8s.io/api v0.0.0-20191025225708-5524a3672fbb
|
||||
k8s.io/apimachinery v0.0.0-20191025225532-af6325b3a843
|
||||
k8s.io/api v0.17.3
|
||||
k8s.io/apimachinery v0.17.3
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/utils v0.0.0-20191010214722-8d271d903fe4
|
||||
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f
|
||||
sigs.k8s.io/yaml v1.1.0
|
||||
)
|
||||
|
||||
replace (
|
||||
golang.org/x/crypto => golang.org/x/crypto v0.0.0-20181025213731-e84da0312774
|
||||
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/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
k8s.io/api => k8s.io/api v0.0.0-20191025225708-5524a3672fbb
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191025225532-af6325b3a843
|
||||
golang.org/x/sys => golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // pinned to release-branch.go1.13
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7 // pinned to release-branch.go1.13
|
||||
k8s.io/api => k8s.io/api v0.17.3
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.17.3
|
||||
)
|
||||
|
||||
93
go.sum
93
go.sum
@@ -72,8 +72,8 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1
|
||||
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=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7 h1:6TSoaYExHper8PYsJu23GWVNOyYRCSnIFyxKgLSZ54w=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/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=
|
||||
@@ -83,8 +83,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
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.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
|
||||
github.com/json-iterator/go v1.1.8/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=
|
||||
@@ -118,35 +118,54 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
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/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503 h1:5SvYFrOM3W8Mexn9/oA44Ji7vhXAZQ9hiP+1Q/DMrWg=
|
||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU=
|
||||
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-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=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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=
|
||||
@@ -162,29 +181,29 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o=
|
||||
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
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=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/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-20191025225708-5524a3672fbb/go.mod h1:NMIXwlJTrA+pXie6lv562GUPkluJ4oRGzQfqWBLaceY=
|
||||
k8s.io/apimachinery v0.0.0-20191025225532-af6325b3a843/go.mod h1:gA1T9z4LIup7PIegBwxkF2UYXUNVKhOAPvQWWnAc34k=
|
||||
k8s.io/api v0.17.3/go.mod h1:YZ0OTkuw7ipbe305fMpIdf3GLXZKRigjtZaV5gzC2J0=
|
||||
k8s.io/apimachinery v0.17.3/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
|
||||
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 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=
|
||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
|
||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
|
||||
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/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=
|
||||
|
||||
@@ -20,6 +20,7 @@ package discovery
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/client-go/informers/discovery/v1alpha1"
|
||||
v1beta1 "k8s.io/client-go/informers/discovery/v1beta1"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
)
|
||||
|
||||
@@ -27,6 +28,8 @@ import (
|
||||
type Interface interface {
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
// V1beta1 provides access to shared informers for resources in V1beta1.
|
||||
V1beta1() v1beta1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
@@ -44,3 +47,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
// V1beta1 returns a new v1beta1.Interface.
|
||||
func (g *group) V1beta1() v1beta1.Interface {
|
||||
return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
89
informers/discovery/v1beta1/endpointslice.go
Normal file
89
informers/discovery/v1beta1/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 v1beta1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
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"
|
||||
v1beta1 "k8s.io/client-go/listers/discovery/v1beta1"
|
||||
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() v1beta1.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.DiscoveryV1beta1().EndpointSlices(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.DiscoveryV1beta1().EndpointSlices(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&discoveryv1beta1.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(&discoveryv1beta1.EndpointSlice{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *endpointSliceInformer) Lister() v1beta1.EndpointSliceLister {
|
||||
return v1beta1.NewEndpointSliceLister(f.Informer().GetIndexer())
|
||||
}
|
||||
45
informers/discovery/v1beta1/interface.go
Normal file
45
informers/discovery/v1beta1/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 v1beta1
|
||||
|
||||
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}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import (
|
||||
discovery "k8s.io/client-go/informers/discovery"
|
||||
events "k8s.io/client-go/informers/events"
|
||||
extensions "k8s.io/client-go/informers/extensions"
|
||||
flowcontrol "k8s.io/client-go/informers/flowcontrol"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
networking "k8s.io/client-go/informers/networking"
|
||||
node "k8s.io/client-go/informers/node"
|
||||
@@ -200,6 +201,7 @@ type SharedInformerFactory interface {
|
||||
Discovery() discovery.Interface
|
||||
Events() events.Interface
|
||||
Extensions() extensions.Interface
|
||||
Flowcontrol() flowcontrol.Interface
|
||||
Networking() networking.Interface
|
||||
Node() node.Interface
|
||||
Policy() policy.Interface
|
||||
@@ -253,6 +255,10 @@ func (f *sharedInformerFactory) Extensions() extensions.Interface {
|
||||
return extensions.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Flowcontrol() flowcontrol.Interface {
|
||||
return flowcontrol.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *sharedInformerFactory) Networking() networking.Interface {
|
||||
return networking.New(f, f.namespace, f.tweakListOptions)
|
||||
}
|
||||
|
||||
46
informers/flowcontrol/interface.go
Normal file
46
informers/flowcontrol/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 flowcontrol
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/client-go/informers/flowcontrol/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)
|
||||
}
|
||||
88
informers/flowcontrol/v1alpha1/flowschema.go
Normal file
88
informers/flowcontrol/v1alpha1/flowschema.go
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
flowcontrolv1alpha1 "k8s.io/api/flowcontrol/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/flowcontrol/v1alpha1"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// FlowSchemaInformer provides access to a shared informer and lister for
|
||||
// FlowSchemas.
|
||||
type FlowSchemaInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.FlowSchemaLister
|
||||
}
|
||||
|
||||
type flowSchemaInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewFlowSchemaInformer constructs a new informer for FlowSchema 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 NewFlowSchemaInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredFlowSchemaInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredFlowSchemaInformer constructs a new informer for FlowSchema 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 NewFilteredFlowSchemaInformer(client kubernetes.Interface, 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.FlowcontrolV1alpha1().FlowSchemas().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.FlowcontrolV1alpha1().FlowSchemas().Watch(options)
|
||||
},
|
||||
},
|
||||
&flowcontrolv1alpha1.FlowSchema{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *flowSchemaInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredFlowSchemaInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *flowSchemaInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&flowcontrolv1alpha1.FlowSchema{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *flowSchemaInformer) Lister() v1alpha1.FlowSchemaLister {
|
||||
return v1alpha1.NewFlowSchemaLister(f.Informer().GetIndexer())
|
||||
}
|
||||
52
informers/flowcontrol/v1alpha1/interface.go
Normal file
52
informers/flowcontrol/v1alpha1/interface.go
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 {
|
||||
// FlowSchemas returns a FlowSchemaInformer.
|
||||
FlowSchemas() FlowSchemaInformer
|
||||
// PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer.
|
||||
PriorityLevelConfigurations() PriorityLevelConfigurationInformer
|
||||
}
|
||||
|
||||
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}
|
||||
}
|
||||
|
||||
// FlowSchemas returns a FlowSchemaInformer.
|
||||
func (v *version) FlowSchemas() FlowSchemaInformer {
|
||||
return &flowSchemaInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// PriorityLevelConfigurations returns a PriorityLevelConfigurationInformer.
|
||||
func (v *version) PriorityLevelConfigurations() PriorityLevelConfigurationInformer {
|
||||
return &priorityLevelConfigurationInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
88
informers/flowcontrol/v1alpha1/prioritylevelconfiguration.go
Normal file
88
informers/flowcontrol/v1alpha1/prioritylevelconfiguration.go
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
flowcontrolv1alpha1 "k8s.io/api/flowcontrol/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/flowcontrol/v1alpha1"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PriorityLevelConfigurationInformer provides access to a shared informer and lister for
|
||||
// PriorityLevelConfigurations.
|
||||
type PriorityLevelConfigurationInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha1.PriorityLevelConfigurationLister
|
||||
}
|
||||
|
||||
type priorityLevelConfigurationInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration 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 NewPriorityLevelConfigurationInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredPriorityLevelConfigurationInformer constructs a new informer for PriorityLevelConfiguration 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 NewFilteredPriorityLevelConfigurationInformer(client kubernetes.Interface, 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.FlowcontrolV1alpha1().PriorityLevelConfigurations().List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.FlowcontrolV1alpha1().PriorityLevelConfigurations().Watch(options)
|
||||
},
|
||||
},
|
||||
&flowcontrolv1alpha1.PriorityLevelConfiguration{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *priorityLevelConfigurationInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredPriorityLevelConfigurationInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *priorityLevelConfigurationInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&flowcontrolv1alpha1.PriorityLevelConfiguration{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *priorityLevelConfigurationInformer) Lister() v1alpha1.PriorityLevelConfigurationLister {
|
||||
return v1alpha1.NewPriorityLevelConfigurationLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -38,8 +38,10 @@ import (
|
||||
coordinationv1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
nodev1alpha1 "k8s.io/api/node/v1alpha1"
|
||||
@@ -207,6 +209,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
case discoveryv1alpha1.SchemeGroupVersion.WithResource("endpointslices"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Discovery().V1alpha1().EndpointSlices().Informer()}, nil
|
||||
|
||||
// Group=discovery.k8s.io, Version=v1beta1
|
||||
case discoveryv1beta1.SchemeGroupVersion.WithResource("endpointslices"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Discovery().V1beta1().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
|
||||
@@ -225,6 +231,12 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
case extensionsv1beta1.SchemeGroupVersion.WithResource("replicasets"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().ReplicaSets().Informer()}, nil
|
||||
|
||||
// Group=flowcontrol.apiserver.k8s.io, Version=v1alpha1
|
||||
case flowcontrolv1alpha1.SchemeGroupVersion.WithResource("flowschemas"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1alpha1().FlowSchemas().Informer()}, nil
|
||||
case flowcontrolv1alpha1.SchemeGroupVersion.WithResource("prioritylevelconfigurations"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Flowcontrol().V1alpha1().PriorityLevelConfigurations().Informer()}, nil
|
||||
|
||||
// Group=networking.k8s.io, Version=v1
|
||||
case networkingv1.SchemeGroupVersion.WithResource("networkpolicies"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1().NetworkPolicies().Informer()}, nil
|
||||
@@ -294,6 +306,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Settings().V1alpha1().PodPresets().Informer()}, nil
|
||||
|
||||
// Group=storage.k8s.io, Version=v1
|
||||
case storagev1.SchemeGroupVersion.WithResource("csinodes"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().CSINodes().Informer()}, nil
|
||||
case storagev1.SchemeGroupVersion.WithResource("storageclasses"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1().StorageClasses().Informer()}, nil
|
||||
case storagev1.SchemeGroupVersion.WithResource("volumeattachments"):
|
||||
|
||||
88
informers/storage/v1/csinode.go
Normal file
88
informers/storage/v1/csinode.go
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
metav1 "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"
|
||||
v1 "k8s.io/client-go/listers/storage/v1"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// CSINodeInformer provides access to a shared informer and lister for
|
||||
// CSINodes.
|
||||
type CSINodeInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1.CSINodeLister
|
||||
}
|
||||
|
||||
type cSINodeInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewCSINodeInformer constructs a new informer for CSINode 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 NewCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredCSINodeInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredCSINodeInformer constructs a new informer for CSINode 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 NewFilteredCSINodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.StorageV1().CSINodes().List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.StorageV1().CSINodes().Watch(options)
|
||||
},
|
||||
},
|
||||
&storagev1.CSINode{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *cSINodeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredCSINodeInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *cSINodeInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&storagev1.CSINode{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *cSINodeInformer) Lister() v1.CSINodeLister {
|
||||
return v1.NewCSINodeLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// CSINodes returns a CSINodeInformer.
|
||||
CSINodes() CSINodeInformer
|
||||
// StorageClasses returns a StorageClassInformer.
|
||||
StorageClasses() StorageClassInformer
|
||||
// VolumeAttachments returns a VolumeAttachmentInformer.
|
||||
@@ -41,6 +43,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// CSINodes returns a CSINodeInformer.
|
||||
func (v *version) CSINodes() CSINodeInformer {
|
||||
return &cSINodeInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// StorageClasses returns a StorageClassInformer.
|
||||
func (v *version) StorageClasses() StorageClassInformer {
|
||||
return &storageClassInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
|
||||
@@ -43,8 +43,10 @@ import (
|
||||
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"
|
||||
discoveryv1beta1 "k8s.io/client-go/kubernetes/typed/discovery/v1beta1"
|
||||
eventsv1beta1 "k8s.io/client-go/kubernetes/typed/events/v1beta1"
|
||||
extensionsv1beta1 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
|
||||
flowcontrolv1alpha1 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1"
|
||||
networkingv1 "k8s.io/client-go/kubernetes/typed/networking/v1"
|
||||
networkingv1beta1 "k8s.io/client-go/kubernetes/typed/networking/v1beta1"
|
||||
nodev1alpha1 "k8s.io/client-go/kubernetes/typed/node/v1alpha1"
|
||||
@@ -87,8 +89,10 @@ type Interface interface {
|
||||
CoordinationV1() coordinationv1.CoordinationV1Interface
|
||||
CoreV1() corev1.CoreV1Interface
|
||||
DiscoveryV1alpha1() discoveryv1alpha1.DiscoveryV1alpha1Interface
|
||||
DiscoveryV1beta1() discoveryv1beta1.DiscoveryV1beta1Interface
|
||||
EventsV1beta1() eventsv1beta1.EventsV1beta1Interface
|
||||
ExtensionsV1beta1() extensionsv1beta1.ExtensionsV1beta1Interface
|
||||
FlowcontrolV1alpha1() flowcontrolv1alpha1.FlowcontrolV1alpha1Interface
|
||||
NetworkingV1() networkingv1.NetworkingV1Interface
|
||||
NetworkingV1beta1() networkingv1beta1.NetworkingV1beta1Interface
|
||||
NodeV1alpha1() nodev1alpha1.NodeV1alpha1Interface
|
||||
@@ -131,8 +135,10 @@ type Clientset struct {
|
||||
coordinationV1 *coordinationv1.CoordinationV1Client
|
||||
coreV1 *corev1.CoreV1Client
|
||||
discoveryV1alpha1 *discoveryv1alpha1.DiscoveryV1alpha1Client
|
||||
discoveryV1beta1 *discoveryv1beta1.DiscoveryV1beta1Client
|
||||
eventsV1beta1 *eventsv1beta1.EventsV1beta1Client
|
||||
extensionsV1beta1 *extensionsv1beta1.ExtensionsV1beta1Client
|
||||
flowcontrolV1alpha1 *flowcontrolv1alpha1.FlowcontrolV1alpha1Client
|
||||
networkingV1 *networkingv1.NetworkingV1Client
|
||||
networkingV1beta1 *networkingv1beta1.NetworkingV1beta1Client
|
||||
nodeV1alpha1 *nodev1alpha1.NodeV1alpha1Client
|
||||
@@ -255,6 +261,11 @@ func (c *Clientset) DiscoveryV1alpha1() discoveryv1alpha1.DiscoveryV1alpha1Inter
|
||||
return c.discoveryV1alpha1
|
||||
}
|
||||
|
||||
// DiscoveryV1beta1 retrieves the DiscoveryV1beta1Client
|
||||
func (c *Clientset) DiscoveryV1beta1() discoveryv1beta1.DiscoveryV1beta1Interface {
|
||||
return c.discoveryV1beta1
|
||||
}
|
||||
|
||||
// EventsV1beta1 retrieves the EventsV1beta1Client
|
||||
func (c *Clientset) EventsV1beta1() eventsv1beta1.EventsV1beta1Interface {
|
||||
return c.eventsV1beta1
|
||||
@@ -265,6 +276,11 @@ func (c *Clientset) ExtensionsV1beta1() extensionsv1beta1.ExtensionsV1beta1Inter
|
||||
return c.extensionsV1beta1
|
||||
}
|
||||
|
||||
// FlowcontrolV1alpha1 retrieves the FlowcontrolV1alpha1Client
|
||||
func (c *Clientset) FlowcontrolV1alpha1() flowcontrolv1alpha1.FlowcontrolV1alpha1Interface {
|
||||
return c.flowcontrolV1alpha1
|
||||
}
|
||||
|
||||
// NetworkingV1 retrieves the NetworkingV1Client
|
||||
func (c *Clientset) NetworkingV1() networkingv1.NetworkingV1Interface {
|
||||
return c.networkingV1
|
||||
@@ -445,6 +461,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.discoveryV1beta1, err = discoveryv1beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.eventsV1beta1, err = eventsv1beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -453,6 +473,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.flowcontrolV1alpha1, err = flowcontrolv1alpha1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.networkingV1, err = networkingv1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -546,8 +570,10 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
cs.coordinationV1 = coordinationv1.NewForConfigOrDie(c)
|
||||
cs.coreV1 = corev1.NewForConfigOrDie(c)
|
||||
cs.discoveryV1alpha1 = discoveryv1alpha1.NewForConfigOrDie(c)
|
||||
cs.discoveryV1beta1 = discoveryv1beta1.NewForConfigOrDie(c)
|
||||
cs.eventsV1beta1 = eventsv1beta1.NewForConfigOrDie(c)
|
||||
cs.extensionsV1beta1 = extensionsv1beta1.NewForConfigOrDie(c)
|
||||
cs.flowcontrolV1alpha1 = flowcontrolv1alpha1.NewForConfigOrDie(c)
|
||||
cs.networkingV1 = networkingv1.NewForConfigOrDie(c)
|
||||
cs.networkingV1beta1 = networkingv1beta1.NewForConfigOrDie(c)
|
||||
cs.nodeV1alpha1 = nodev1alpha1.NewForConfigOrDie(c)
|
||||
@@ -592,8 +618,10 @@ func New(c rest.Interface) *Clientset {
|
||||
cs.coordinationV1 = coordinationv1.New(c)
|
||||
cs.coreV1 = corev1.New(c)
|
||||
cs.discoveryV1alpha1 = discoveryv1alpha1.New(c)
|
||||
cs.discoveryV1beta1 = discoveryv1beta1.New(c)
|
||||
cs.eventsV1beta1 = eventsv1beta1.New(c)
|
||||
cs.extensionsV1beta1 = extensionsv1beta1.New(c)
|
||||
cs.flowcontrolV1alpha1 = flowcontrolv1alpha1.New(c)
|
||||
cs.networkingV1 = networkingv1.New(c)
|
||||
cs.networkingV1beta1 = networkingv1beta1.New(c)
|
||||
cs.nodeV1alpha1 = nodev1alpha1.New(c)
|
||||
|
||||
@@ -66,10 +66,14 @@ import (
|
||||
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"
|
||||
discoveryv1beta1 "k8s.io/client-go/kubernetes/typed/discovery/v1beta1"
|
||||
fakediscoveryv1beta1 "k8s.io/client-go/kubernetes/typed/discovery/v1beta1/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"
|
||||
fakeextensionsv1beta1 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1/fake"
|
||||
flowcontrolv1alpha1 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1"
|
||||
fakeflowcontrolv1alpha1 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1/fake"
|
||||
networkingv1 "k8s.io/client-go/kubernetes/typed/networking/v1"
|
||||
fakenetworkingv1 "k8s.io/client-go/kubernetes/typed/networking/v1/fake"
|
||||
networkingv1beta1 "k8s.io/client-go/kubernetes/typed/networking/v1beta1"
|
||||
@@ -255,6 +259,11 @@ func (c *Clientset) DiscoveryV1alpha1() discoveryv1alpha1.DiscoveryV1alpha1Inter
|
||||
return &fakediscoveryv1alpha1.FakeDiscoveryV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// DiscoveryV1beta1 retrieves the DiscoveryV1beta1Client
|
||||
func (c *Clientset) DiscoveryV1beta1() discoveryv1beta1.DiscoveryV1beta1Interface {
|
||||
return &fakediscoveryv1beta1.FakeDiscoveryV1beta1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// EventsV1beta1 retrieves the EventsV1beta1Client
|
||||
func (c *Clientset) EventsV1beta1() eventsv1beta1.EventsV1beta1Interface {
|
||||
return &fakeeventsv1beta1.FakeEventsV1beta1{Fake: &c.Fake}
|
||||
@@ -265,6 +274,11 @@ func (c *Clientset) ExtensionsV1beta1() extensionsv1beta1.ExtensionsV1beta1Inter
|
||||
return &fakeextensionsv1beta1.FakeExtensionsV1beta1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// FlowcontrolV1alpha1 retrieves the FlowcontrolV1alpha1Client
|
||||
func (c *Clientset) FlowcontrolV1alpha1() flowcontrolv1alpha1.FlowcontrolV1alpha1Interface {
|
||||
return &fakeflowcontrolv1alpha1.FakeFlowcontrolV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// NetworkingV1 retrieves the NetworkingV1Client
|
||||
func (c *Clientset) NetworkingV1() networkingv1.NetworkingV1Interface {
|
||||
return &fakenetworkingv1.FakeNetworkingV1{Fake: &c.Fake}
|
||||
|
||||
@@ -40,8 +40,10 @@ import (
|
||||
coordinationv1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
nodev1alpha1 "k8s.io/api/node/v1alpha1"
|
||||
@@ -89,8 +91,10 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
coordinationv1.AddToScheme,
|
||||
corev1.AddToScheme,
|
||||
discoveryv1alpha1.AddToScheme,
|
||||
discoveryv1beta1.AddToScheme,
|
||||
eventsv1beta1.AddToScheme,
|
||||
extensionsv1beta1.AddToScheme,
|
||||
flowcontrolv1alpha1.AddToScheme,
|
||||
networkingv1.AddToScheme,
|
||||
networkingv1beta1.AddToScheme,
|
||||
nodev1alpha1.AddToScheme,
|
||||
|
||||
@@ -40,8 +40,10 @@ import (
|
||||
coordinationv1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1"
|
||||
networkingv1 "k8s.io/api/networking/v1"
|
||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||
nodev1alpha1 "k8s.io/api/node/v1alpha1"
|
||||
@@ -89,8 +91,10 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
coordinationv1.AddToScheme,
|
||||
corev1.AddToScheme,
|
||||
discoveryv1alpha1.AddToScheme,
|
||||
discoveryv1beta1.AddToScheme,
|
||||
eventsv1beta1.AddToScheme,
|
||||
extensionsv1beta1.AddToScheme,
|
||||
flowcontrolv1alpha1.AddToScheme,
|
||||
networkingv1.AddToScheme,
|
||||
networkingv1beta1.AddToScheme,
|
||||
nodev1alpha1.AddToScheme,
|
||||
|
||||
89
kubernetes/typed/discovery/v1beta1/discovery_client.go
Normal file
89
kubernetes/typed/discovery/v1beta1/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 v1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type DiscoveryV1beta1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
EndpointSlicesGetter
|
||||
}
|
||||
|
||||
// DiscoveryV1beta1Client is used to interact with features provided by the discovery.k8s.io group.
|
||||
type DiscoveryV1beta1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *DiscoveryV1beta1Client) EndpointSlices(namespace string) EndpointSliceInterface {
|
||||
return newEndpointSlices(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new DiscoveryV1beta1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*DiscoveryV1beta1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DiscoveryV1beta1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new DiscoveryV1beta1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *DiscoveryV1beta1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new DiscoveryV1beta1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *DiscoveryV1beta1Client {
|
||||
return &DiscoveryV1beta1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1beta1.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 *DiscoveryV1beta1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
20
kubernetes/typed/discovery/v1beta1/doc.go
Normal file
20
kubernetes/typed/discovery/v1beta1/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 v1beta1
|
||||
174
kubernetes/typed/discovery/v1beta1/endpointslice.go
Normal file
174
kubernetes/typed/discovery/v1beta1/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 v1beta1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
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(*v1beta1.EndpointSlice) (*v1beta1.EndpointSlice, error)
|
||||
Update(*v1beta1.EndpointSlice) (*v1beta1.EndpointSlice, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1beta1.EndpointSlice, error)
|
||||
List(opts v1.ListOptions) (*v1beta1.EndpointSliceList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.EndpointSlice, err error)
|
||||
EndpointSliceExpansion
|
||||
}
|
||||
|
||||
// endpointSlices implements EndpointSliceInterface
|
||||
type endpointSlices struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newEndpointSlices returns a EndpointSlices
|
||||
func newEndpointSlices(c *DiscoveryV1beta1Client, 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 *v1beta1.EndpointSlice, err error) {
|
||||
result = &v1beta1.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 *v1beta1.EndpointSliceList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.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 *v1beta1.EndpointSlice) (result *v1beta1.EndpointSlice, err error) {
|
||||
result = &v1beta1.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 *v1beta1.EndpointSlice) (result *v1beta1.EndpointSlice, err error) {
|
||||
result = &v1beta1.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 *v1beta1.EndpointSlice, err error) {
|
||||
result = &v1beta1.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/v1beta1/fake/doc.go
Normal file
20
kubernetes/typed/discovery/v1beta1/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 (
|
||||
v1beta1 "k8s.io/client-go/kubernetes/typed/discovery/v1beta1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeDiscoveryV1beta1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeDiscoveryV1beta1) EndpointSlices(namespace string) v1beta1.EndpointSliceInterface {
|
||||
return &FakeEndpointSlices{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeDiscoveryV1beta1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
128
kubernetes/typed/discovery/v1beta1/fake/fake_endpointslice.go
Normal file
128
kubernetes/typed/discovery/v1beta1/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 (
|
||||
v1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
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 *FakeDiscoveryV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var endpointslicesResource = schema.GroupVersionResource{Group: "discovery.k8s.io", Version: "v1beta1", Resource: "endpointslices"}
|
||||
|
||||
var endpointslicesKind = schema.GroupVersionKind{Group: "discovery.k8s.io", Version: "v1beta1", 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 *v1beta1.EndpointSlice, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(endpointslicesResource, c.ns, name), &v1beta1.EndpointSlice{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.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 *v1beta1.EndpointSliceList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(endpointslicesResource, endpointslicesKind, c.ns, opts), &v1beta1.EndpointSliceList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.EndpointSliceList{ListMeta: obj.(*v1beta1.EndpointSliceList).ListMeta}
|
||||
for _, item := range obj.(*v1beta1.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 *v1beta1.EndpointSlice) (result *v1beta1.EndpointSlice, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(endpointslicesResource, c.ns, endpointSlice), &v1beta1.EndpointSlice{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.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 *v1beta1.EndpointSlice) (result *v1beta1.EndpointSlice, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(endpointslicesResource, c.ns, endpointSlice), &v1beta1.EndpointSlice{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.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), &v1beta1.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, &v1beta1.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 *v1beta1.EndpointSlice, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(endpointslicesResource, c.ns, name, pt, data, subresources...), &v1beta1.EndpointSlice{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.EndpointSlice), err
|
||||
}
|
||||
21
kubernetes/typed/discovery/v1beta1/generated_expansion.go
Normal file
21
kubernetes/typed/discovery/v1beta1/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 v1beta1
|
||||
|
||||
type EndpointSliceExpansion interface{}
|
||||
20
kubernetes/typed/flowcontrol/v1alpha1/doc.go
Normal file
20
kubernetes/typed/flowcontrol/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
|
||||
20
kubernetes/typed/flowcontrol/v1alpha1/fake/doc.go
Normal file
20
kubernetes/typed/flowcontrol/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,44 @@
|
||||
/*
|
||||
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/flowcontrol/v1alpha1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeFlowcontrolV1alpha1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeFlowcontrolV1alpha1) FlowSchemas() v1alpha1.FlowSchemaInterface {
|
||||
return &FakeFlowSchemas{c}
|
||||
}
|
||||
|
||||
func (c *FakeFlowcontrolV1alpha1) PriorityLevelConfigurations() v1alpha1.PriorityLevelConfigurationInterface {
|
||||
return &FakePriorityLevelConfigurations{c}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeFlowcontrolV1alpha1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
131
kubernetes/typed/flowcontrol/v1alpha1/fake/fake_flowschema.go
Normal file
131
kubernetes/typed/flowcontrol/v1alpha1/fake/fake_flowschema.go
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
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/flowcontrol/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"
|
||||
)
|
||||
|
||||
// FakeFlowSchemas implements FlowSchemaInterface
|
||||
type FakeFlowSchemas struct {
|
||||
Fake *FakeFlowcontrolV1alpha1
|
||||
}
|
||||
|
||||
var flowschemasResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Resource: "flowschemas"}
|
||||
|
||||
var flowschemasKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Kind: "FlowSchema"}
|
||||
|
||||
// Get takes name of the flowSchema, and returns the corresponding flowSchema object, and an error if there is any.
|
||||
func (c *FakeFlowSchemas) Get(name string, options v1.GetOptions) (result *v1alpha1.FlowSchema, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(flowschemasResource, name), &v1alpha1.FlowSchema{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.FlowSchema), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of FlowSchemas that match those selectors.
|
||||
func (c *FakeFlowSchemas) List(opts v1.ListOptions) (result *v1alpha1.FlowSchemaList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(flowschemasResource, flowschemasKind, opts), &v1alpha1.FlowSchemaList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.FlowSchemaList{ListMeta: obj.(*v1alpha1.FlowSchemaList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.FlowSchemaList).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 flowSchemas.
|
||||
func (c *FakeFlowSchemas) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(flowschemasResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a flowSchema and creates it. Returns the server's representation of the flowSchema, and an error, if there is any.
|
||||
func (c *FakeFlowSchemas) Create(flowSchema *v1alpha1.FlowSchema) (result *v1alpha1.FlowSchema, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(flowschemasResource, flowSchema), &v1alpha1.FlowSchema{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.FlowSchema), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a flowSchema and updates it. Returns the server's representation of the flowSchema, and an error, if there is any.
|
||||
func (c *FakeFlowSchemas) Update(flowSchema *v1alpha1.FlowSchema) (result *v1alpha1.FlowSchema, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(flowschemasResource, flowSchema), &v1alpha1.FlowSchema{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.FlowSchema), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeFlowSchemas) UpdateStatus(flowSchema *v1alpha1.FlowSchema) (*v1alpha1.FlowSchema, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(flowschemasResource, "status", flowSchema), &v1alpha1.FlowSchema{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.FlowSchema), err
|
||||
}
|
||||
|
||||
// Delete takes name of the flowSchema and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeFlowSchemas) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(flowschemasResource, name), &v1alpha1.FlowSchema{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeFlowSchemas) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(flowschemasResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.FlowSchemaList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched flowSchema.
|
||||
func (c *FakeFlowSchemas) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.FlowSchema, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(flowschemasResource, name, pt, data, subresources...), &v1alpha1.FlowSchema{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.FlowSchema), err
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
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/flowcontrol/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"
|
||||
)
|
||||
|
||||
// FakePriorityLevelConfigurations implements PriorityLevelConfigurationInterface
|
||||
type FakePriorityLevelConfigurations struct {
|
||||
Fake *FakeFlowcontrolV1alpha1
|
||||
}
|
||||
|
||||
var prioritylevelconfigurationsResource = schema.GroupVersionResource{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Resource: "prioritylevelconfigurations"}
|
||||
|
||||
var prioritylevelconfigurationsKind = schema.GroupVersionKind{Group: "flowcontrol.apiserver.k8s.io", Version: "v1alpha1", Kind: "PriorityLevelConfiguration"}
|
||||
|
||||
// Get takes name of the priorityLevelConfiguration, and returns the corresponding priorityLevelConfiguration object, and an error if there is any.
|
||||
func (c *FakePriorityLevelConfigurations) Get(name string, options v1.GetOptions) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(prioritylevelconfigurationsResource, name), &v1alpha1.PriorityLevelConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PriorityLevelConfiguration), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PriorityLevelConfigurations that match those selectors.
|
||||
func (c *FakePriorityLevelConfigurations) List(opts v1.ListOptions) (result *v1alpha1.PriorityLevelConfigurationList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(prioritylevelconfigurationsResource, prioritylevelconfigurationsKind, opts), &v1alpha1.PriorityLevelConfigurationList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.PriorityLevelConfigurationList{ListMeta: obj.(*v1alpha1.PriorityLevelConfigurationList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha1.PriorityLevelConfigurationList).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 priorityLevelConfigurations.
|
||||
func (c *FakePriorityLevelConfigurations) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(prioritylevelconfigurationsResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a priorityLevelConfiguration and creates it. Returns the server's representation of the priorityLevelConfiguration, and an error, if there is any.
|
||||
func (c *FakePriorityLevelConfigurations) Create(priorityLevelConfiguration *v1alpha1.PriorityLevelConfiguration) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(prioritylevelconfigurationsResource, priorityLevelConfiguration), &v1alpha1.PriorityLevelConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PriorityLevelConfiguration), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a priorityLevelConfiguration and updates it. Returns the server's representation of the priorityLevelConfiguration, and an error, if there is any.
|
||||
func (c *FakePriorityLevelConfigurations) Update(priorityLevelConfiguration *v1alpha1.PriorityLevelConfiguration) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(prioritylevelconfigurationsResource, priorityLevelConfiguration), &v1alpha1.PriorityLevelConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PriorityLevelConfiguration), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakePriorityLevelConfigurations) UpdateStatus(priorityLevelConfiguration *v1alpha1.PriorityLevelConfiguration) (*v1alpha1.PriorityLevelConfiguration, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(prioritylevelconfigurationsResource, "status", priorityLevelConfiguration), &v1alpha1.PriorityLevelConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PriorityLevelConfiguration), err
|
||||
}
|
||||
|
||||
// Delete takes name of the priorityLevelConfiguration and deletes it. Returns an error if one occurs.
|
||||
func (c *FakePriorityLevelConfigurations) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(prioritylevelconfigurationsResource, name), &v1alpha1.PriorityLevelConfiguration{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakePriorityLevelConfigurations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(prioritylevelconfigurationsResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.PriorityLevelConfigurationList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched priorityLevelConfiguration.
|
||||
func (c *FakePriorityLevelConfigurations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(prioritylevelconfigurationsResource, name, pt, data, subresources...), &v1alpha1.PriorityLevelConfiguration{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PriorityLevelConfiguration), err
|
||||
}
|
||||
94
kubernetes/typed/flowcontrol/v1alpha1/flowcontrol_client.go
Normal file
94
kubernetes/typed/flowcontrol/v1alpha1/flowcontrol_client.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 client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1alpha1 "k8s.io/api/flowcontrol/v1alpha1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type FlowcontrolV1alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
FlowSchemasGetter
|
||||
PriorityLevelConfigurationsGetter
|
||||
}
|
||||
|
||||
// FlowcontrolV1alpha1Client is used to interact with features provided by the flowcontrol.apiserver.k8s.io group.
|
||||
type FlowcontrolV1alpha1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *FlowcontrolV1alpha1Client) FlowSchemas() FlowSchemaInterface {
|
||||
return newFlowSchemas(c)
|
||||
}
|
||||
|
||||
func (c *FlowcontrolV1alpha1Client) PriorityLevelConfigurations() PriorityLevelConfigurationInterface {
|
||||
return newPriorityLevelConfigurations(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new FlowcontrolV1alpha1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*FlowcontrolV1alpha1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &FlowcontrolV1alpha1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new FlowcontrolV1alpha1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *FlowcontrolV1alpha1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new FlowcontrolV1alpha1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *FlowcontrolV1alpha1Client {
|
||||
return &FlowcontrolV1alpha1Client{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 *FlowcontrolV1alpha1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
180
kubernetes/typed/flowcontrol/v1alpha1/flowschema.go
Normal file
180
kubernetes/typed/flowcontrol/v1alpha1/flowschema.go
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
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/flowcontrol/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"
|
||||
)
|
||||
|
||||
// FlowSchemasGetter has a method to return a FlowSchemaInterface.
|
||||
// A group's client should implement this interface.
|
||||
type FlowSchemasGetter interface {
|
||||
FlowSchemas() FlowSchemaInterface
|
||||
}
|
||||
|
||||
// FlowSchemaInterface has methods to work with FlowSchema resources.
|
||||
type FlowSchemaInterface interface {
|
||||
Create(*v1alpha1.FlowSchema) (*v1alpha1.FlowSchema, error)
|
||||
Update(*v1alpha1.FlowSchema) (*v1alpha1.FlowSchema, error)
|
||||
UpdateStatus(*v1alpha1.FlowSchema) (*v1alpha1.FlowSchema, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha1.FlowSchema, error)
|
||||
List(opts v1.ListOptions) (*v1alpha1.FlowSchemaList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.FlowSchema, err error)
|
||||
FlowSchemaExpansion
|
||||
}
|
||||
|
||||
// flowSchemas implements FlowSchemaInterface
|
||||
type flowSchemas struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newFlowSchemas returns a FlowSchemas
|
||||
func newFlowSchemas(c *FlowcontrolV1alpha1Client) *flowSchemas {
|
||||
return &flowSchemas{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the flowSchema, and returns the corresponding flowSchema object, and an error if there is any.
|
||||
func (c *flowSchemas) Get(name string, options v1.GetOptions) (result *v1alpha1.FlowSchema, err error) {
|
||||
result = &v1alpha1.FlowSchema{}
|
||||
err = c.client.Get().
|
||||
Resource("flowschemas").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of FlowSchemas that match those selectors.
|
||||
func (c *flowSchemas) List(opts v1.ListOptions) (result *v1alpha1.FlowSchemaList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.FlowSchemaList{}
|
||||
err = c.client.Get().
|
||||
Resource("flowschemas").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested flowSchemas.
|
||||
func (c *flowSchemas) 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().
|
||||
Resource("flowschemas").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a flowSchema and creates it. Returns the server's representation of the flowSchema, and an error, if there is any.
|
||||
func (c *flowSchemas) Create(flowSchema *v1alpha1.FlowSchema) (result *v1alpha1.FlowSchema, err error) {
|
||||
result = &v1alpha1.FlowSchema{}
|
||||
err = c.client.Post().
|
||||
Resource("flowschemas").
|
||||
Body(flowSchema).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a flowSchema and updates it. Returns the server's representation of the flowSchema, and an error, if there is any.
|
||||
func (c *flowSchemas) Update(flowSchema *v1alpha1.FlowSchema) (result *v1alpha1.FlowSchema, err error) {
|
||||
result = &v1alpha1.FlowSchema{}
|
||||
err = c.client.Put().
|
||||
Resource("flowschemas").
|
||||
Name(flowSchema.Name).
|
||||
Body(flowSchema).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *flowSchemas) UpdateStatus(flowSchema *v1alpha1.FlowSchema) (result *v1alpha1.FlowSchema, err error) {
|
||||
result = &v1alpha1.FlowSchema{}
|
||||
err = c.client.Put().
|
||||
Resource("flowschemas").
|
||||
Name(flowSchema.Name).
|
||||
SubResource("status").
|
||||
Body(flowSchema).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the flowSchema and deletes it. Returns an error if one occurs.
|
||||
func (c *flowSchemas) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("flowschemas").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *flowSchemas) 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().
|
||||
Resource("flowschemas").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched flowSchema.
|
||||
func (c *flowSchemas) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.FlowSchema, err error) {
|
||||
result = &v1alpha1.FlowSchema{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("flowschemas").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
23
kubernetes/typed/flowcontrol/v1alpha1/generated_expansion.go
Normal file
23
kubernetes/typed/flowcontrol/v1alpha1/generated_expansion.go
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
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 FlowSchemaExpansion interface{}
|
||||
|
||||
type PriorityLevelConfigurationExpansion interface{}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
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/flowcontrol/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"
|
||||
)
|
||||
|
||||
// PriorityLevelConfigurationsGetter has a method to return a PriorityLevelConfigurationInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PriorityLevelConfigurationsGetter interface {
|
||||
PriorityLevelConfigurations() PriorityLevelConfigurationInterface
|
||||
}
|
||||
|
||||
// PriorityLevelConfigurationInterface has methods to work with PriorityLevelConfiguration resources.
|
||||
type PriorityLevelConfigurationInterface interface {
|
||||
Create(*v1alpha1.PriorityLevelConfiguration) (*v1alpha1.PriorityLevelConfiguration, error)
|
||||
Update(*v1alpha1.PriorityLevelConfiguration) (*v1alpha1.PriorityLevelConfiguration, error)
|
||||
UpdateStatus(*v1alpha1.PriorityLevelConfiguration) (*v1alpha1.PriorityLevelConfiguration, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha1.PriorityLevelConfiguration, error)
|
||||
List(opts v1.ListOptions) (*v1alpha1.PriorityLevelConfigurationList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PriorityLevelConfiguration, err error)
|
||||
PriorityLevelConfigurationExpansion
|
||||
}
|
||||
|
||||
// priorityLevelConfigurations implements PriorityLevelConfigurationInterface
|
||||
type priorityLevelConfigurations struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newPriorityLevelConfigurations returns a PriorityLevelConfigurations
|
||||
func newPriorityLevelConfigurations(c *FlowcontrolV1alpha1Client) *priorityLevelConfigurations {
|
||||
return &priorityLevelConfigurations{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the priorityLevelConfiguration, and returns the corresponding priorityLevelConfiguration object, and an error if there is any.
|
||||
func (c *priorityLevelConfigurations) Get(name string, options v1.GetOptions) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
result = &v1alpha1.PriorityLevelConfiguration{}
|
||||
err = c.client.Get().
|
||||
Resource("prioritylevelconfigurations").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PriorityLevelConfigurations that match those selectors.
|
||||
func (c *priorityLevelConfigurations) List(opts v1.ListOptions) (result *v1alpha1.PriorityLevelConfigurationList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1alpha1.PriorityLevelConfigurationList{}
|
||||
err = c.client.Get().
|
||||
Resource("prioritylevelconfigurations").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested priorityLevelConfigurations.
|
||||
func (c *priorityLevelConfigurations) 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().
|
||||
Resource("prioritylevelconfigurations").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a priorityLevelConfiguration and creates it. Returns the server's representation of the priorityLevelConfiguration, and an error, if there is any.
|
||||
func (c *priorityLevelConfigurations) Create(priorityLevelConfiguration *v1alpha1.PriorityLevelConfiguration) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
result = &v1alpha1.PriorityLevelConfiguration{}
|
||||
err = c.client.Post().
|
||||
Resource("prioritylevelconfigurations").
|
||||
Body(priorityLevelConfiguration).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a priorityLevelConfiguration and updates it. Returns the server's representation of the priorityLevelConfiguration, and an error, if there is any.
|
||||
func (c *priorityLevelConfigurations) Update(priorityLevelConfiguration *v1alpha1.PriorityLevelConfiguration) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
result = &v1alpha1.PriorityLevelConfiguration{}
|
||||
err = c.client.Put().
|
||||
Resource("prioritylevelconfigurations").
|
||||
Name(priorityLevelConfiguration.Name).
|
||||
Body(priorityLevelConfiguration).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *priorityLevelConfigurations) UpdateStatus(priorityLevelConfiguration *v1alpha1.PriorityLevelConfiguration) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
result = &v1alpha1.PriorityLevelConfiguration{}
|
||||
err = c.client.Put().
|
||||
Resource("prioritylevelconfigurations").
|
||||
Name(priorityLevelConfiguration.Name).
|
||||
SubResource("status").
|
||||
Body(priorityLevelConfiguration).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the priorityLevelConfiguration and deletes it. Returns an error if one occurs.
|
||||
func (c *priorityLevelConfigurations) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("prioritylevelconfigurations").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *priorityLevelConfigurations) 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().
|
||||
Resource("prioritylevelconfigurations").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched priorityLevelConfiguration.
|
||||
func (c *priorityLevelConfigurations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
result = &v1alpha1.PriorityLevelConfiguration{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("prioritylevelconfigurations").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
164
kubernetes/typed/storage/v1/csinode.go
Normal file
164
kubernetes/typed/storage/v1/csinode.go
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/storage/v1"
|
||||
metav1 "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"
|
||||
)
|
||||
|
||||
// CSINodesGetter has a method to return a CSINodeInterface.
|
||||
// A group's client should implement this interface.
|
||||
type CSINodesGetter interface {
|
||||
CSINodes() CSINodeInterface
|
||||
}
|
||||
|
||||
// CSINodeInterface has methods to work with CSINode resources.
|
||||
type CSINodeInterface interface {
|
||||
Create(*v1.CSINode) (*v1.CSINode, error)
|
||||
Update(*v1.CSINode) (*v1.CSINode, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error
|
||||
Get(name string, options metav1.GetOptions) (*v1.CSINode, error)
|
||||
List(opts metav1.ListOptions) (*v1.CSINodeList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.CSINode, err error)
|
||||
CSINodeExpansion
|
||||
}
|
||||
|
||||
// cSINodes implements CSINodeInterface
|
||||
type cSINodes struct {
|
||||
client rest.Interface
|
||||
}
|
||||
|
||||
// newCSINodes returns a CSINodes
|
||||
func newCSINodes(c *StorageV1Client) *cSINodes {
|
||||
return &cSINodes{
|
||||
client: c.RESTClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the cSINode, and returns the corresponding cSINode object, and an error if there is any.
|
||||
func (c *cSINodes) Get(name string, options metav1.GetOptions) (result *v1.CSINode, err error) {
|
||||
result = &v1.CSINode{}
|
||||
err = c.client.Get().
|
||||
Resource("csinodes").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of CSINodes that match those selectors.
|
||||
func (c *cSINodes) List(opts metav1.ListOptions) (result *v1.CSINodeList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1.CSINodeList{}
|
||||
err = c.client.Get().
|
||||
Resource("csinodes").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested cSINodes.
|
||||
func (c *cSINodes) Watch(opts metav1.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().
|
||||
Resource("csinodes").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a cSINode and creates it. Returns the server's representation of the cSINode, and an error, if there is any.
|
||||
func (c *cSINodes) Create(cSINode *v1.CSINode) (result *v1.CSINode, err error) {
|
||||
result = &v1.CSINode{}
|
||||
err = c.client.Post().
|
||||
Resource("csinodes").
|
||||
Body(cSINode).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a cSINode and updates it. Returns the server's representation of the cSINode, and an error, if there is any.
|
||||
func (c *cSINodes) Update(cSINode *v1.CSINode) (result *v1.CSINode, err error) {
|
||||
result = &v1.CSINode{}
|
||||
err = c.client.Put().
|
||||
Resource("csinodes").
|
||||
Name(cSINode.Name).
|
||||
Body(cSINode).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the cSINode and deletes it. Returns an error if one occurs.
|
||||
func (c *cSINodes) Delete(name string, options *metav1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Resource("csinodes").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *cSINodes) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Resource("csinodes").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched cSINode.
|
||||
func (c *cSINodes) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.CSINode, err error) {
|
||||
result = &v1.CSINode{}
|
||||
err = c.client.Patch(pt).
|
||||
Resource("csinodes").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
120
kubernetes/typed/storage/v1/fake/fake_csinode.go
Normal file
120
kubernetes/typed/storage/v1/fake/fake_csinode.go
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
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 (
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
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"
|
||||
)
|
||||
|
||||
// FakeCSINodes implements CSINodeInterface
|
||||
type FakeCSINodes struct {
|
||||
Fake *FakeStorageV1
|
||||
}
|
||||
|
||||
var csinodesResource = schema.GroupVersionResource{Group: "storage.k8s.io", Version: "v1", Resource: "csinodes"}
|
||||
|
||||
var csinodesKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1", Kind: "CSINode"}
|
||||
|
||||
// Get takes name of the cSINode, and returns the corresponding cSINode object, and an error if there is any.
|
||||
func (c *FakeCSINodes) Get(name string, options v1.GetOptions) (result *storagev1.CSINode, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(csinodesResource, name), &storagev1.CSINode{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*storagev1.CSINode), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of CSINodes that match those selectors.
|
||||
func (c *FakeCSINodes) List(opts v1.ListOptions) (result *storagev1.CSINodeList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(csinodesResource, csinodesKind, opts), &storagev1.CSINodeList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &storagev1.CSINodeList{ListMeta: obj.(*storagev1.CSINodeList).ListMeta}
|
||||
for _, item := range obj.(*storagev1.CSINodeList).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 cSINodes.
|
||||
func (c *FakeCSINodes) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(csinodesResource, opts))
|
||||
}
|
||||
|
||||
// Create takes the representation of a cSINode and creates it. Returns the server's representation of the cSINode, and an error, if there is any.
|
||||
func (c *FakeCSINodes) Create(cSINode *storagev1.CSINode) (result *storagev1.CSINode, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(csinodesResource, cSINode), &storagev1.CSINode{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*storagev1.CSINode), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a cSINode and updates it. Returns the server's representation of the cSINode, and an error, if there is any.
|
||||
func (c *FakeCSINodes) Update(cSINode *storagev1.CSINode) (result *storagev1.CSINode, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(csinodesResource, cSINode), &storagev1.CSINode{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*storagev1.CSINode), err
|
||||
}
|
||||
|
||||
// Delete takes name of the cSINode and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeCSINodes) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(csinodesResource, name), &storagev1.CSINode{})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeCSINodes) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(csinodesResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &storagev1.CSINodeList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched cSINode.
|
||||
func (c *FakeCSINodes) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *storagev1.CSINode, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(csinodesResource, name, pt, data, subresources...), &storagev1.CSINode{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*storagev1.CSINode), err
|
||||
}
|
||||
@@ -28,6 +28,10 @@ type FakeStorageV1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeStorageV1) CSINodes() v1.CSINodeInterface {
|
||||
return &FakeCSINodes{c}
|
||||
}
|
||||
|
||||
func (c *FakeStorageV1) StorageClasses() v1.StorageClassInterface {
|
||||
return &FakeStorageClasses{c}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
type CSINodeExpansion interface{}
|
||||
|
||||
type StorageClassExpansion interface{}
|
||||
|
||||
type VolumeAttachmentExpansion interface{}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
type StorageV1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
CSINodesGetter
|
||||
StorageClassesGetter
|
||||
VolumeAttachmentsGetter
|
||||
}
|
||||
@@ -35,6 +36,10 @@ type StorageV1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *StorageV1Client) CSINodes() CSINodeInterface {
|
||||
return newCSINodes(c)
|
||||
}
|
||||
|
||||
func (c *StorageV1Client) StorageClasses() StorageClassInterface {
|
||||
return newStorageClasses(c)
|
||||
}
|
||||
|
||||
94
listers/discovery/v1beta1/endpointslice.go
Normal file
94
listers/discovery/v1beta1/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 v1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "k8s.io/api/discovery/v1beta1"
|
||||
"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 []*v1beta1.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 []*v1beta1.EndpointSlice, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.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 []*v1beta1.EndpointSlice, err error)
|
||||
// Get retrieves the EndpointSlice from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1beta1.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 []*v1beta1.EndpointSlice, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.EndpointSlice))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the EndpointSlice from the indexer for a given namespace and name.
|
||||
func (s endpointSliceNamespaceLister) Get(name string) (*v1beta1.EndpointSlice, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta1.Resource("endpointslice"), name)
|
||||
}
|
||||
return obj.(*v1beta1.EndpointSlice), nil
|
||||
}
|
||||
27
listers/discovery/v1beta1/expansion_generated.go
Normal file
27
listers/discovery/v1beta1/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 v1beta1
|
||||
|
||||
// EndpointSliceListerExpansion allows custom methods to be added to
|
||||
// EndpointSliceLister.
|
||||
type EndpointSliceListerExpansion interface{}
|
||||
|
||||
// EndpointSliceNamespaceListerExpansion allows custom methods to be added to
|
||||
// EndpointSliceNamespaceLister.
|
||||
type EndpointSliceNamespaceListerExpansion interface{}
|
||||
27
listers/flowcontrol/v1alpha1/expansion_generated.go
Normal file
27
listers/flowcontrol/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
|
||||
|
||||
// FlowSchemaListerExpansion allows custom methods to be added to
|
||||
// FlowSchemaLister.
|
||||
type FlowSchemaListerExpansion interface{}
|
||||
|
||||
// PriorityLevelConfigurationListerExpansion allows custom methods to be added to
|
||||
// PriorityLevelConfigurationLister.
|
||||
type PriorityLevelConfigurationListerExpansion interface{}
|
||||
65
listers/flowcontrol/v1alpha1/flowschema.go
Normal file
65
listers/flowcontrol/v1alpha1/flowschema.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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/flowcontrol/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// FlowSchemaLister helps list FlowSchemas.
|
||||
type FlowSchemaLister interface {
|
||||
// List lists all FlowSchemas in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.FlowSchema, err error)
|
||||
// Get retrieves the FlowSchema from the index for a given name.
|
||||
Get(name string) (*v1alpha1.FlowSchema, error)
|
||||
FlowSchemaListerExpansion
|
||||
}
|
||||
|
||||
// flowSchemaLister implements the FlowSchemaLister interface.
|
||||
type flowSchemaLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewFlowSchemaLister returns a new FlowSchemaLister.
|
||||
func NewFlowSchemaLister(indexer cache.Indexer) FlowSchemaLister {
|
||||
return &flowSchemaLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all FlowSchemas in the indexer.
|
||||
func (s *flowSchemaLister) List(selector labels.Selector) (ret []*v1alpha1.FlowSchema, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.FlowSchema))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the FlowSchema from the index for a given name.
|
||||
func (s *flowSchemaLister) Get(name string) (*v1alpha1.FlowSchema, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("flowschema"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.FlowSchema), nil
|
||||
}
|
||||
65
listers/flowcontrol/v1alpha1/prioritylevelconfiguration.go
Normal file
65
listers/flowcontrol/v1alpha1/prioritylevelconfiguration.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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/flowcontrol/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PriorityLevelConfigurationLister helps list PriorityLevelConfigurations.
|
||||
type PriorityLevelConfigurationLister interface {
|
||||
// List lists all PriorityLevelConfigurations in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha1.PriorityLevelConfiguration, err error)
|
||||
// Get retrieves the PriorityLevelConfiguration from the index for a given name.
|
||||
Get(name string) (*v1alpha1.PriorityLevelConfiguration, error)
|
||||
PriorityLevelConfigurationListerExpansion
|
||||
}
|
||||
|
||||
// priorityLevelConfigurationLister implements the PriorityLevelConfigurationLister interface.
|
||||
type priorityLevelConfigurationLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewPriorityLevelConfigurationLister returns a new PriorityLevelConfigurationLister.
|
||||
func NewPriorityLevelConfigurationLister(indexer cache.Indexer) PriorityLevelConfigurationLister {
|
||||
return &priorityLevelConfigurationLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all PriorityLevelConfigurations in the indexer.
|
||||
func (s *priorityLevelConfigurationLister) List(selector labels.Selector) (ret []*v1alpha1.PriorityLevelConfiguration, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha1.PriorityLevelConfiguration))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the PriorityLevelConfiguration from the index for a given name.
|
||||
func (s *priorityLevelConfigurationLister) Get(name string) (*v1alpha1.PriorityLevelConfiguration, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha1.Resource("prioritylevelconfiguration"), name)
|
||||
}
|
||||
return obj.(*v1alpha1.PriorityLevelConfiguration), nil
|
||||
}
|
||||
65
listers/storage/v1/csinode.go
Normal file
65
listers/storage/v1/csinode.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// CSINodeLister helps list CSINodes.
|
||||
type CSINodeLister interface {
|
||||
// List lists all CSINodes in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1.CSINode, err error)
|
||||
// Get retrieves the CSINode from the index for a given name.
|
||||
Get(name string) (*v1.CSINode, error)
|
||||
CSINodeListerExpansion
|
||||
}
|
||||
|
||||
// cSINodeLister implements the CSINodeLister interface.
|
||||
type cSINodeLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewCSINodeLister returns a new CSINodeLister.
|
||||
func NewCSINodeLister(indexer cache.Indexer) CSINodeLister {
|
||||
return &cSINodeLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all CSINodes in the indexer.
|
||||
func (s *cSINodeLister) List(selector labels.Selector) (ret []*v1.CSINode, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1.CSINode))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the CSINode from the index for a given name.
|
||||
func (s *cSINodeLister) Get(name string) (*v1.CSINode, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1.Resource("csinode"), name)
|
||||
}
|
||||
return obj.(*v1.CSINode), nil
|
||||
}
|
||||
@@ -18,6 +18,10 @@ limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
// CSINodeListerExpansion allows custom methods to be added to
|
||||
// CSINodeLister.
|
||||
type CSINodeListerExpansion interface{}
|
||||
|
||||
// StorageClassListerExpansion allows custom methods to be added to
|
||||
// StorageClassLister.
|
||||
type StorageClassListerExpansion interface{}
|
||||
|
||||
@@ -317,7 +317,6 @@ func (c *metadataResourceClient) List(opts metav1.ListOptions) (*metav1.PartialO
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("incoming object is incorrect type %T", obj)
|
||||
}
|
||||
fmt.Printf("DEBUG: %#v\n", inputList)
|
||||
|
||||
list := &metav1.PartialObjectMetadataList{
|
||||
ListMeta: inputList.ListMeta,
|
||||
|
||||
@@ -48,6 +48,7 @@ import (
|
||||
)
|
||||
|
||||
const execInfoEnv = "KUBERNETES_EXEC_INFO"
|
||||
const onRotateListWarningLength = 1000
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
@@ -164,7 +165,7 @@ type Authenticator struct {
|
||||
cachedCreds *credentials
|
||||
exp time.Time
|
||||
|
||||
onRotate func()
|
||||
onRotateList []func()
|
||||
}
|
||||
|
||||
type credentials struct {
|
||||
@@ -191,7 +192,15 @@ func (a *Authenticator) UpdateTransportConfig(c *transport.Config) error {
|
||||
dial = (&net.Dialer{Timeout: 30 * time.Second, KeepAlive: 30 * time.Second}).DialContext
|
||||
}
|
||||
d := connrotation.NewDialer(dial)
|
||||
a.onRotate = d.CloseAll
|
||||
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
a.onRotateList = append(a.onRotateList, d.CloseAll)
|
||||
onRotateListLength := len(a.onRotateList)
|
||||
if onRotateListLength > onRotateListWarningLength {
|
||||
klog.Warningf("constructing many client instances from the same exec auth config can cause performance problems during cert rotation and can exhaust available network connections; %d clients constructed calling %q", onRotateListLength, a.cmd)
|
||||
}
|
||||
|
||||
c.Dial = d.DialContext
|
||||
|
||||
return nil
|
||||
@@ -353,8 +362,10 @@ func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) err
|
||||
a.cachedCreds = newCreds
|
||||
// Only close all connections when TLS cert rotates. Token rotation doesn't
|
||||
// need the extra noise.
|
||||
if a.onRotate != nil && oldCreds != nil && !reflect.DeepEqual(oldCreds.cert, a.cachedCreds.cert) {
|
||||
a.onRotate()
|
||||
if len(a.onRotateList) > 0 && oldCreds != nil && !reflect.DeepEqual(oldCreds.cert, a.cachedCreds.cert) {
|
||||
for _, onRotate := range a.onRotateList {
|
||||
onRotate()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -713,6 +713,52 @@ func TestTLSCredentials(t *testing.T) {
|
||||
get(t, "valid TLS cert again", false)
|
||||
}
|
||||
|
||||
func TestConcurrentUpdateTransportConfig(t *testing.T) {
|
||||
n := time.Now()
|
||||
now := func() time.Time { return n }
|
||||
|
||||
env := []string{""}
|
||||
environ := func() []string {
|
||||
s := make([]string, len(env))
|
||||
copy(s, env)
|
||||
return s
|
||||
}
|
||||
|
||||
c := api.ExecConfig{
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
}
|
||||
a, err := newAuthenticator(newCache(), &c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
a.environ = environ
|
||||
a.now = now
|
||||
a.stderr = ioutil.Discard
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
|
||||
numConcurrent := 2
|
||||
|
||||
for i := 0; i < numConcurrent; i++ {
|
||||
go func() {
|
||||
for {
|
||||
tc := &transport.Config{}
|
||||
a.UpdateTransportConfig(tc)
|
||||
|
||||
select {
|
||||
case <-stopCh:
|
||||
return
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
// genClientCert generates an x509 certificate for testing. Certificate and key
|
||||
// are returned in PEM encoding.
|
||||
func genClientCert(t *testing.T) ([]byte, []byte) {
|
||||
|
||||
@@ -476,25 +476,25 @@ func Test_cmdTokenSource_roundTrip(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
"Unauthorized",
|
||||
http.Response{StatusCode: 401},
|
||||
http.Response{StatusCode: http.StatusUnauthorized},
|
||||
make(map[string]string),
|
||||
make(map[string]string),
|
||||
},
|
||||
{
|
||||
"Unauthorized, nonempty defaultCache",
|
||||
http.Response{StatusCode: 401},
|
||||
http.Response{StatusCode: http.StatusUnauthorized},
|
||||
cmdCache,
|
||||
cmdCache,
|
||||
},
|
||||
{
|
||||
"Authorized",
|
||||
http.Response{StatusCode: 200},
|
||||
http.Response{StatusCode: http.StatusOK},
|
||||
make(map[string]string),
|
||||
simpleCacheUpdated,
|
||||
},
|
||||
{
|
||||
"Authorized, nonempty defaultCache",
|
||||
http.Response{StatusCode: 200},
|
||||
http.Response{StatusCode: http.StatusOK},
|
||||
cmdCache,
|
||||
cmdCacheUpdated,
|
||||
},
|
||||
|
||||
141
rest/client.go
141
rest/client.go
@@ -17,8 +17,6 @@ limitations under the License.
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -51,6 +49,28 @@ type Interface interface {
|
||||
APIVersion() schema.GroupVersion
|
||||
}
|
||||
|
||||
// ClientContentConfig controls how RESTClient communicates with the server.
|
||||
//
|
||||
// TODO: ContentConfig will be updated to accept a Negotiator instead of a
|
||||
// NegotiatedSerializer and NegotiatedSerializer will be removed.
|
||||
type ClientContentConfig struct {
|
||||
// AcceptContentTypes specifies the types the client will accept and is optional.
|
||||
// If not set, ContentType will be used to define the Accept header
|
||||
AcceptContentTypes string
|
||||
// ContentType specifies the wire format used to communicate with the server.
|
||||
// This value will be set as the Accept header on requests made to the server if
|
||||
// AcceptContentTypes is not set, and as the default content type on any object
|
||||
// sent to the server. If not set, "application/json" is used.
|
||||
ContentType string
|
||||
// GroupVersion is the API version to talk to. Must be provided when initializing
|
||||
// a RESTClient directly. When initializing a Client, will be set with the default
|
||||
// code version. This is used as the default group version for VersionedParams.
|
||||
GroupVersion schema.GroupVersion
|
||||
// Negotiator is used for obtaining encoders and decoders for multiple
|
||||
// supported media types.
|
||||
Negotiator runtime.ClientNegotiator
|
||||
}
|
||||
|
||||
// RESTClient imposes common Kubernetes API conventions on a set of resource paths.
|
||||
// The baseURL is expected to point to an HTTP or HTTPS path that is the parent
|
||||
// of one or more resources. The server should return a decodable API resource
|
||||
@@ -64,34 +84,27 @@ type RESTClient struct {
|
||||
// versionedAPIPath is a path segment connecting the base URL to the resource root
|
||||
versionedAPIPath string
|
||||
|
||||
// contentConfig is the information used to communicate with the server.
|
||||
contentConfig ContentConfig
|
||||
|
||||
// serializers contain all serializers for underlying content type.
|
||||
serializers Serializers
|
||||
// content describes how a RESTClient encodes and decodes responses.
|
||||
content ClientContentConfig
|
||||
|
||||
// creates BackoffManager that is passed to requests.
|
||||
createBackoffMgr func() BackoffManager
|
||||
|
||||
// TODO extract this into a wrapper interface via the RESTClient interface in kubectl.
|
||||
Throttle flowcontrol.RateLimiter
|
||||
// rateLimiter is shared among all requests created by this client unless specifically
|
||||
// overridden.
|
||||
rateLimiter flowcontrol.RateLimiter
|
||||
|
||||
// Set specific behavior of the client. If not set http.DefaultClient will be used.
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
type Serializers struct {
|
||||
Encoder runtime.Encoder
|
||||
Decoder runtime.Decoder
|
||||
StreamingSerializer runtime.Serializer
|
||||
Framer runtime.Framer
|
||||
RenegotiatedDecoder func(contentType string, params map[string]string) (runtime.Decoder, error)
|
||||
}
|
||||
|
||||
// NewRESTClient creates a new RESTClient. This client performs generic REST functions
|
||||
// such as Get, Put, Post, and Delete on specified paths. Codec controls encoding and
|
||||
// decoding of responses from the server.
|
||||
func NewRESTClient(baseURL *url.URL, versionedAPIPath string, config ContentConfig, maxQPS float32, maxBurst int, rateLimiter flowcontrol.RateLimiter, client *http.Client) (*RESTClient, error) {
|
||||
// such as Get, Put, Post, and Delete on specified paths.
|
||||
func NewRESTClient(baseURL *url.URL, versionedAPIPath string, config ClientContentConfig, rateLimiter flowcontrol.RateLimiter, client *http.Client) (*RESTClient, error) {
|
||||
if len(config.ContentType) == 0 {
|
||||
config.ContentType = "application/json"
|
||||
}
|
||||
|
||||
base := *baseURL
|
||||
if !strings.HasSuffix(base.Path, "/") {
|
||||
base.Path += "/"
|
||||
@@ -99,31 +112,14 @@ func NewRESTClient(baseURL *url.URL, versionedAPIPath string, config ContentConf
|
||||
base.RawQuery = ""
|
||||
base.Fragment = ""
|
||||
|
||||
if config.GroupVersion == nil {
|
||||
config.GroupVersion = &schema.GroupVersion{}
|
||||
}
|
||||
if len(config.ContentType) == 0 {
|
||||
config.ContentType = "application/json"
|
||||
}
|
||||
serializers, err := createSerializers(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var throttle flowcontrol.RateLimiter
|
||||
if maxQPS > 0 && rateLimiter == nil {
|
||||
throttle = flowcontrol.NewTokenBucketRateLimiter(maxQPS, maxBurst)
|
||||
} else if rateLimiter != nil {
|
||||
throttle = rateLimiter
|
||||
}
|
||||
return &RESTClient{
|
||||
base: &base,
|
||||
versionedAPIPath: versionedAPIPath,
|
||||
contentConfig: config,
|
||||
serializers: *serializers,
|
||||
content: config,
|
||||
createBackoffMgr: readExpBackoffConfig,
|
||||
Throttle: throttle,
|
||||
Client: client,
|
||||
rateLimiter: rateLimiter,
|
||||
|
||||
Client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -132,7 +128,7 @@ func (c *RESTClient) GetRateLimiter() flowcontrol.RateLimiter {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.Throttle
|
||||
return c.rateLimiter
|
||||
}
|
||||
|
||||
// readExpBackoffConfig handles the internal logic of determining what the
|
||||
@@ -153,58 +149,6 @@ func readExpBackoffConfig() BackoffManager {
|
||||
time.Duration(backoffDurationInt)*time.Second)}
|
||||
}
|
||||
|
||||
// createSerializers creates all necessary serializers for given contentType.
|
||||
// TODO: the negotiated serializer passed to this method should probably return
|
||||
// serializers that control decoding and versioning without this package
|
||||
// being aware of the types. Depends on whether RESTClient must deal with
|
||||
// generic infrastructure.
|
||||
func createSerializers(config ContentConfig) (*Serializers, error) {
|
||||
mediaTypes := config.NegotiatedSerializer.SupportedMediaTypes()
|
||||
contentType := config.ContentType
|
||||
mediaType, _, err := mime.ParseMediaType(contentType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the content type specified in the client configuration is not recognized: %v", err)
|
||||
}
|
||||
info, ok := runtime.SerializerInfoForMediaType(mediaTypes, mediaType)
|
||||
if !ok {
|
||||
if len(contentType) != 0 || len(mediaTypes) == 0 {
|
||||
return nil, fmt.Errorf("no serializers registered for %s", contentType)
|
||||
}
|
||||
info = mediaTypes[0]
|
||||
}
|
||||
|
||||
internalGV := schema.GroupVersions{
|
||||
{
|
||||
Group: config.GroupVersion.Group,
|
||||
Version: runtime.APIVersionInternal,
|
||||
},
|
||||
// always include the legacy group as a decoding target to handle non-error `Status` return types
|
||||
{
|
||||
Group: "",
|
||||
Version: runtime.APIVersionInternal,
|
||||
},
|
||||
}
|
||||
|
||||
s := &Serializers{
|
||||
Encoder: config.NegotiatedSerializer.EncoderForVersion(info.Serializer, *config.GroupVersion),
|
||||
Decoder: config.NegotiatedSerializer.DecoderToVersion(info.Serializer, internalGV),
|
||||
|
||||
RenegotiatedDecoder: func(contentType string, params map[string]string) (runtime.Decoder, error) {
|
||||
info, ok := runtime.SerializerInfoForMediaType(mediaTypes, contentType)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("serializer for %s not registered", contentType)
|
||||
}
|
||||
return config.NegotiatedSerializer.DecoderToVersion(info.Serializer, internalGV), nil
|
||||
},
|
||||
}
|
||||
if info.StreamSerializer != nil {
|
||||
s.StreamingSerializer = info.StreamSerializer.Serializer
|
||||
s.Framer = info.StreamSerializer.Framer
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Verb begins a request with a verb (GET, POST, PUT, DELETE).
|
||||
//
|
||||
// Example usage of RESTClient's request building interface:
|
||||
@@ -219,12 +163,7 @@ func createSerializers(config ContentConfig) (*Serializers, error) {
|
||||
// list, ok := resp.(*api.PodList)
|
||||
//
|
||||
func (c *RESTClient) Verb(verb string) *Request {
|
||||
backoff := c.createBackoffMgr()
|
||||
|
||||
if c.Client == nil {
|
||||
return NewRequest(nil, verb, c.base, c.versionedAPIPath, c.contentConfig, c.serializers, backoff, c.Throttle, 0)
|
||||
}
|
||||
return NewRequest(c.Client, verb, c.base, c.versionedAPIPath, c.contentConfig, c.serializers, backoff, c.Throttle, c.Client.Timeout)
|
||||
return NewRequest(c).Verb(verb)
|
||||
}
|
||||
|
||||
// Post begins a POST request. Short for c.Verb("POST").
|
||||
@@ -254,5 +193,5 @@ func (c *RESTClient) Delete() *Request {
|
||||
|
||||
// APIVersion returns the APIVersion this RESTClient is expected to use.
|
||||
func (c *RESTClient) APIVersion() schema.GroupVersion {
|
||||
return *c.contentConfig.GroupVersion
|
||||
return c.content.GroupVersion
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
v1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -57,12 +57,14 @@ func TestSerializer(t *testing.T) {
|
||||
NegotiatedSerializer: scheme.Codecs.WithoutConversion(),
|
||||
}
|
||||
|
||||
serializer, err := createSerializers(contentConfig)
|
||||
n := runtime.NewClientNegotiator(contentConfig.NegotiatedSerializer, gv)
|
||||
d, err := n.Decoder("application/json", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// bytes based on actual return from API server when encoding an "unversioned" object
|
||||
obj, err := runtime.Decode(serializer.Decoder, []byte(`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Success"}`))
|
||||
obj, err := runtime.Decode(d, []byte(`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Success"}`))
|
||||
t.Log(obj)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -269,6 +269,9 @@ type ContentConfig struct {
|
||||
GroupVersion *schema.GroupVersion
|
||||
// NegotiatedSerializer is used for obtaining encoders and decoders for multiple
|
||||
// supported media types.
|
||||
//
|
||||
// TODO: NegotiatedSerializer will be phased out as internal clients are removed
|
||||
// from Kubernetes.
|
||||
NegotiatedSerializer runtime.NegotiatedSerializer
|
||||
}
|
||||
|
||||
@@ -283,14 +286,6 @@ func RESTClientFor(config *Config) (*RESTClient, error) {
|
||||
if config.NegotiatedSerializer == nil {
|
||||
return nil, fmt.Errorf("NegotiatedSerializer is required when initializing a RESTClient")
|
||||
}
|
||||
qps := config.QPS
|
||||
if config.QPS == 0.0 {
|
||||
qps = DefaultQPS
|
||||
}
|
||||
burst := config.Burst
|
||||
if config.Burst == 0 {
|
||||
burst = DefaultBurst
|
||||
}
|
||||
|
||||
baseURL, versionedAPIPath, err := defaultServerUrlFor(config)
|
||||
if err != nil {
|
||||
@@ -310,7 +305,33 @@ func RESTClientFor(config *Config) (*RESTClient, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return NewRESTClient(baseURL, versionedAPIPath, config.ContentConfig, qps, burst, config.RateLimiter, httpClient)
|
||||
rateLimiter := config.RateLimiter
|
||||
if rateLimiter == nil {
|
||||
qps := config.QPS
|
||||
if config.QPS == 0.0 {
|
||||
qps = DefaultQPS
|
||||
}
|
||||
burst := config.Burst
|
||||
if config.Burst == 0 {
|
||||
burst = DefaultBurst
|
||||
}
|
||||
if qps > 0 {
|
||||
rateLimiter = flowcontrol.NewTokenBucketRateLimiter(qps, burst)
|
||||
}
|
||||
}
|
||||
|
||||
var gv schema.GroupVersion
|
||||
if config.GroupVersion != nil {
|
||||
gv = *config.GroupVersion
|
||||
}
|
||||
clientContent := ClientContentConfig{
|
||||
AcceptContentTypes: config.AcceptContentTypes,
|
||||
ContentType: config.ContentType,
|
||||
GroupVersion: gv,
|
||||
Negotiator: runtime.NewClientNegotiator(config.NegotiatedSerializer, gv),
|
||||
}
|
||||
|
||||
return NewRESTClient(baseURL, versionedAPIPath, clientContent, rateLimiter, httpClient)
|
||||
}
|
||||
|
||||
// UnversionedRESTClientFor is the same as RESTClientFor, except that it allows
|
||||
@@ -338,13 +359,33 @@ func UnversionedRESTClientFor(config *Config) (*RESTClient, error) {
|
||||
}
|
||||
}
|
||||
|
||||
versionConfig := config.ContentConfig
|
||||
if versionConfig.GroupVersion == nil {
|
||||
v := metav1.SchemeGroupVersion
|
||||
versionConfig.GroupVersion = &v
|
||||
rateLimiter := config.RateLimiter
|
||||
if rateLimiter == nil {
|
||||
qps := config.QPS
|
||||
if config.QPS == 0.0 {
|
||||
qps = DefaultQPS
|
||||
}
|
||||
burst := config.Burst
|
||||
if config.Burst == 0 {
|
||||
burst = DefaultBurst
|
||||
}
|
||||
if qps > 0 {
|
||||
rateLimiter = flowcontrol.NewTokenBucketRateLimiter(qps, burst)
|
||||
}
|
||||
}
|
||||
|
||||
return NewRESTClient(baseURL, versionedAPIPath, versionConfig, config.QPS, config.Burst, config.RateLimiter, httpClient)
|
||||
gv := metav1.SchemeGroupVersion
|
||||
if config.GroupVersion != nil {
|
||||
gv = *config.GroupVersion
|
||||
}
|
||||
clientContent := ClientContentConfig{
|
||||
AcceptContentTypes: config.AcceptContentTypes,
|
||||
ContentType: config.ContentType,
|
||||
GroupVersion: gv,
|
||||
Negotiator: runtime.NewClientNegotiator(config.NegotiatedSerializer, gv),
|
||||
}
|
||||
|
||||
return NewRESTClient(baseURL, versionedAPIPath, clientContent, rateLimiter, httpClient)
|
||||
}
|
||||
|
||||
// SetKubernetesDefaults sets default values on the provided client config for accessing the
|
||||
|
||||
@@ -155,6 +155,59 @@ func TestRESTClientRequires(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTClientLimiter(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Config Config
|
||||
Limiter flowcontrol.RateLimiter
|
||||
}{
|
||||
{
|
||||
Config: Config{},
|
||||
Limiter: flowcontrol.NewTokenBucketRateLimiter(5, 10),
|
||||
},
|
||||
{
|
||||
Config: Config{QPS: 10},
|
||||
Limiter: flowcontrol.NewTokenBucketRateLimiter(10, 10),
|
||||
},
|
||||
{
|
||||
Config: Config{QPS: -1},
|
||||
Limiter: nil,
|
||||
},
|
||||
{
|
||||
Config: Config{
|
||||
RateLimiter: flowcontrol.NewTokenBucketRateLimiter(11, 12),
|
||||
},
|
||||
Limiter: flowcontrol.NewTokenBucketRateLimiter(11, 12),
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
t.Run("Versioned_"+testCase.Name, func(t *testing.T) {
|
||||
config := testCase.Config
|
||||
config.Host = "127.0.0.1"
|
||||
config.ContentConfig = ContentConfig{GroupVersion: &v1.SchemeGroupVersion, NegotiatedSerializer: scheme.Codecs}
|
||||
client, err := RESTClientFor(&config)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(testCase.Limiter, client.rateLimiter) {
|
||||
t.Fatalf("unexpected rate limiter: %#v", client.rateLimiter)
|
||||
}
|
||||
})
|
||||
t.Run("Unversioned_"+testCase.Name, func(t *testing.T) {
|
||||
config := testCase.Config
|
||||
config.Host = "127.0.0.1"
|
||||
config.ContentConfig = ContentConfig{GroupVersion: &v1.SchemeGroupVersion, NegotiatedSerializer: scheme.Codecs}
|
||||
client, err := UnversionedRESTClientFor(&config)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(testCase.Limiter, client.rateLimiter) {
|
||||
t.Fatalf("unexpected rate limiter: %#v", client.rateLimiter)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeLimiter struct {
|
||||
FakeSaturation float64
|
||||
FakeQPS float32
|
||||
|
||||
@@ -29,6 +29,8 @@ import (
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
// CreateHTTPClient creates an http.Client that will invoke the provided roundTripper func
|
||||
// when a request is made.
|
||||
func CreateHTTPClient(roundTripper func(*http.Request) (*http.Response, error)) *http.Client {
|
||||
return &http.Client{
|
||||
Transport: roundTripperFunc(roundTripper),
|
||||
@@ -41,40 +43,49 @@ func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return f(req)
|
||||
}
|
||||
|
||||
// RESTClient provides a fake RESTClient interface.
|
||||
// RESTClient provides a fake RESTClient interface. It is used to mock network
|
||||
// interactions via a rest.Request, or to make them via the provided Client to
|
||||
// a specific server.
|
||||
type RESTClient struct {
|
||||
Client *http.Client
|
||||
NegotiatedSerializer runtime.NegotiatedSerializer
|
||||
GroupVersion schema.GroupVersion
|
||||
VersionedAPIPath string
|
||||
|
||||
Req *http.Request
|
||||
// Err is returned when any request would be made to the server. If Err is set,
|
||||
// Req will not be recorded, Resp will not be returned, and Client will not be
|
||||
// invoked.
|
||||
Err error
|
||||
// Req is set to the last request that was executed (had the methods Do/DoRaw) invoked.
|
||||
Req *http.Request
|
||||
// If Client is specified, the client will be invoked instead of returning Resp if
|
||||
// Err is not set.
|
||||
Client *http.Client
|
||||
// Resp is returned to the caller after Req is recorded, unless Err or Client are set.
|
||||
Resp *http.Response
|
||||
Err error
|
||||
}
|
||||
|
||||
func (c *RESTClient) Get() *restclient.Request {
|
||||
return c.request("GET")
|
||||
return c.Verb("GET")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Put() *restclient.Request {
|
||||
return c.request("PUT")
|
||||
return c.Verb("PUT")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Patch(pt types.PatchType) *restclient.Request {
|
||||
return c.request("PATCH").SetHeader("Content-Type", string(pt))
|
||||
return c.Verb("PATCH").SetHeader("Content-Type", string(pt))
|
||||
}
|
||||
|
||||
func (c *RESTClient) Post() *restclient.Request {
|
||||
return c.request("POST")
|
||||
return c.Verb("POST")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Delete() *restclient.Request {
|
||||
return c.request("DELETE")
|
||||
return c.Verb("DELETE")
|
||||
}
|
||||
|
||||
func (c *RESTClient) Verb(verb string) *restclient.Request {
|
||||
return c.request(verb)
|
||||
return c.Request().Verb(verb)
|
||||
}
|
||||
|
||||
func (c *RESTClient) APIVersion() schema.GroupVersion {
|
||||
@@ -85,28 +96,17 @@ func (c *RESTClient) GetRateLimiter() flowcontrol.RateLimiter {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RESTClient) request(verb string) *restclient.Request {
|
||||
config := restclient.ContentConfig{
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
GroupVersion: &c.GroupVersion,
|
||||
NegotiatedSerializer: c.NegotiatedSerializer,
|
||||
func (c *RESTClient) Request() *restclient.Request {
|
||||
config := restclient.ClientContentConfig{
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
GroupVersion: c.GroupVersion,
|
||||
Negotiator: runtime.NewClientNegotiator(c.NegotiatedSerializer, c.GroupVersion),
|
||||
}
|
||||
|
||||
ns := c.NegotiatedSerializer
|
||||
info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
serializers := restclient.Serializers{
|
||||
// TODO this was hardcoded before, but it doesn't look right
|
||||
Encoder: ns.EncoderForVersion(info.Serializer, c.GroupVersion),
|
||||
Decoder: ns.DecoderToVersion(info.Serializer, c.GroupVersion),
|
||||
}
|
||||
if info.StreamSerializer != nil {
|
||||
serializers.StreamingSerializer = info.StreamSerializer.Serializer
|
||||
serializers.Framer = info.StreamSerializer.Framer
|
||||
}
|
||||
return restclient.NewRequest(c, verb, &url.URL{Host: "localhost"}, c.VersionedAPIPath, config, serializers, nil, nil, 0)
|
||||
return restclient.NewRequestWithClient(&url.URL{Scheme: "https", Host: "localhost"}, c.VersionedAPIPath, config, CreateHTTPClient(c.do))
|
||||
}
|
||||
|
||||
func (c *RESTClient) Do(req *http.Request) (*http.Response, error) {
|
||||
// do is invoked when a Request() created by this client is executed.
|
||||
func (c *RESTClient) do(req *http.Request) (*http.Response, error) {
|
||||
if c.Err != nil {
|
||||
return nil, c.Err
|
||||
}
|
||||
|
||||
198
rest/request.go
198
rest/request.go
@@ -48,7 +48,8 @@ import (
|
||||
|
||||
var (
|
||||
// longThrottleLatency defines threshold for logging requests. All requests being
|
||||
// throttle for more than longThrottleLatency will be logged.
|
||||
// throttled (via the provided rateLimiter) for more than longThrottleLatency will
|
||||
// be logged.
|
||||
longThrottleLatency = 50 * time.Millisecond
|
||||
)
|
||||
|
||||
@@ -74,19 +75,20 @@ func (r *RequestConstructionError) Error() string {
|
||||
return fmt.Sprintf("request construction error: '%v'", r.Err)
|
||||
}
|
||||
|
||||
var noBackoff = &NoBackoff{}
|
||||
|
||||
// Request allows for building up a request to a server in a chained fashion.
|
||||
// Any errors are stored until the end of your call, so you only have to
|
||||
// check once.
|
||||
type Request struct {
|
||||
// required
|
||||
client HTTPClient
|
||||
verb string
|
||||
c *RESTClient
|
||||
|
||||
baseURL *url.URL
|
||||
content ContentConfig
|
||||
serializers Serializers
|
||||
rateLimiter flowcontrol.RateLimiter
|
||||
backoff BackoffManager
|
||||
timeout time.Duration
|
||||
|
||||
// generic components accessible via method setters
|
||||
verb string
|
||||
pathPrefix string
|
||||
subpath string
|
||||
params url.Values
|
||||
@@ -98,7 +100,6 @@ type Request struct {
|
||||
resource string
|
||||
resourceName string
|
||||
subresource string
|
||||
timeout time.Duration
|
||||
|
||||
// output
|
||||
err error
|
||||
@@ -106,42 +107,63 @@ type Request struct {
|
||||
|
||||
// This is only used for per-request timeouts, deadlines, and cancellations.
|
||||
ctx context.Context
|
||||
|
||||
backoffMgr BackoffManager
|
||||
throttle flowcontrol.RateLimiter
|
||||
}
|
||||
|
||||
// NewRequest creates a new request helper object for accessing runtime.Objects on a server.
|
||||
func NewRequest(client HTTPClient, verb string, baseURL *url.URL, versionedAPIPath string, content ContentConfig, serializers Serializers, backoff BackoffManager, throttle flowcontrol.RateLimiter, timeout time.Duration) *Request {
|
||||
func NewRequest(c *RESTClient) *Request {
|
||||
var backoff BackoffManager
|
||||
if c.createBackoffMgr != nil {
|
||||
backoff = c.createBackoffMgr()
|
||||
}
|
||||
if backoff == nil {
|
||||
klog.V(2).Infof("Not implementing request backoff strategy.")
|
||||
backoff = &NoBackoff{}
|
||||
backoff = noBackoff
|
||||
}
|
||||
|
||||
pathPrefix := "/"
|
||||
if baseURL != nil {
|
||||
pathPrefix = path.Join(pathPrefix, baseURL.Path)
|
||||
var pathPrefix string
|
||||
if c.base != nil {
|
||||
pathPrefix = path.Join("/", c.base.Path, c.versionedAPIPath)
|
||||
} else {
|
||||
pathPrefix = path.Join("/", c.versionedAPIPath)
|
||||
}
|
||||
|
||||
var timeout time.Duration
|
||||
if c.Client != nil {
|
||||
timeout = c.Client.Timeout
|
||||
}
|
||||
|
||||
r := &Request{
|
||||
client: client,
|
||||
verb: verb,
|
||||
baseURL: baseURL,
|
||||
pathPrefix: path.Join(pathPrefix, versionedAPIPath),
|
||||
content: content,
|
||||
serializers: serializers,
|
||||
backoffMgr: backoff,
|
||||
throttle: throttle,
|
||||
c: c,
|
||||
rateLimiter: c.rateLimiter,
|
||||
backoff: backoff,
|
||||
timeout: timeout,
|
||||
pathPrefix: pathPrefix,
|
||||
}
|
||||
|
||||
switch {
|
||||
case len(content.AcceptContentTypes) > 0:
|
||||
r.SetHeader("Accept", content.AcceptContentTypes)
|
||||
case len(content.ContentType) > 0:
|
||||
r.SetHeader("Accept", content.ContentType+", */*")
|
||||
case len(c.content.AcceptContentTypes) > 0:
|
||||
r.SetHeader("Accept", c.content.AcceptContentTypes)
|
||||
case len(c.content.ContentType) > 0:
|
||||
r.SetHeader("Accept", c.content.ContentType+", */*")
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// NewRequestWithClient creates a Request with an embedded RESTClient for use in test scenarios.
|
||||
func NewRequestWithClient(base *url.URL, versionedAPIPath string, content ClientContentConfig, client *http.Client) *Request {
|
||||
return NewRequest(&RESTClient{
|
||||
base: base,
|
||||
versionedAPIPath: versionedAPIPath,
|
||||
content: content,
|
||||
Client: client,
|
||||
})
|
||||
}
|
||||
|
||||
// Verb sets the verb this request will use.
|
||||
func (r *Request) Verb(verb string) *Request {
|
||||
r.verb = verb
|
||||
return r
|
||||
}
|
||||
|
||||
// Prefix adds segments to the relative beginning to the request path. These
|
||||
// items will be placed before the optional Namespace, Resource, or Name sections.
|
||||
// Setting AbsPath will clear any previously set Prefix segments
|
||||
@@ -184,17 +206,17 @@ func (r *Request) Resource(resource string) *Request {
|
||||
// or defaults to the stub implementation if nil is provided
|
||||
func (r *Request) BackOff(manager BackoffManager) *Request {
|
||||
if manager == nil {
|
||||
r.backoffMgr = &NoBackoff{}
|
||||
r.backoff = &NoBackoff{}
|
||||
return r
|
||||
}
|
||||
|
||||
r.backoffMgr = manager
|
||||
r.backoff = manager
|
||||
return r
|
||||
}
|
||||
|
||||
// Throttle receives a rate-limiter and sets or replaces an existing request limiter
|
||||
func (r *Request) Throttle(limiter flowcontrol.RateLimiter) *Request {
|
||||
r.throttle = limiter
|
||||
r.rateLimiter = limiter
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -272,8 +294,8 @@ func (r *Request) AbsPath(segments ...string) *Request {
|
||||
if r.err != nil {
|
||||
return r
|
||||
}
|
||||
r.pathPrefix = path.Join(r.baseURL.Path, path.Join(segments...))
|
||||
if len(segments) == 1 && (len(r.baseURL.Path) > 1 || len(segments[0]) > 1) && strings.HasSuffix(segments[0], "/") {
|
||||
r.pathPrefix = path.Join(r.c.base.Path, path.Join(segments...))
|
||||
if len(segments) == 1 && (len(r.c.base.Path) > 1 || len(segments[0]) > 1) && strings.HasSuffix(segments[0], "/") {
|
||||
// preserve any trailing slashes for legacy behavior
|
||||
r.pathPrefix += "/"
|
||||
}
|
||||
@@ -317,7 +339,7 @@ func (r *Request) Param(paramName, s string) *Request {
|
||||
// VersionedParams will not write query parameters that have omitempty set and are empty. If a
|
||||
// parameter has already been set it is appended to (Params and VersionedParams are additive).
|
||||
func (r *Request) VersionedParams(obj runtime.Object, codec runtime.ParameterCodec) *Request {
|
||||
return r.SpecificallyVersionedParams(obj, codec, *r.content.GroupVersion)
|
||||
return r.SpecificallyVersionedParams(obj, codec, r.c.content.GroupVersion)
|
||||
}
|
||||
|
||||
func (r *Request) SpecificallyVersionedParams(obj runtime.Object, codec runtime.ParameterCodec, version schema.GroupVersion) *Request {
|
||||
@@ -397,14 +419,19 @@ func (r *Request) Body(obj interface{}) *Request {
|
||||
if reflect.ValueOf(t).IsNil() {
|
||||
return r
|
||||
}
|
||||
data, err := runtime.Encode(r.serializers.Encoder, t)
|
||||
encoder, err := r.c.content.Negotiator.Encoder(r.c.content.ContentType, nil)
|
||||
if err != nil {
|
||||
r.err = err
|
||||
return r
|
||||
}
|
||||
data, err := runtime.Encode(encoder, t)
|
||||
if err != nil {
|
||||
r.err = err
|
||||
return r
|
||||
}
|
||||
glogBody("Request Body", data)
|
||||
r.body = bytes.NewReader(data)
|
||||
r.SetHeader("Content-Type", r.content.ContentType)
|
||||
r.SetHeader("Content-Type", r.c.content.ContentType)
|
||||
default:
|
||||
r.err = fmt.Errorf("unknown type used for body: %+v", obj)
|
||||
}
|
||||
@@ -433,8 +460,8 @@ func (r *Request) URL() *url.URL {
|
||||
}
|
||||
|
||||
finalURL := &url.URL{}
|
||||
if r.baseURL != nil {
|
||||
*finalURL = *r.baseURL
|
||||
if r.c.base != nil {
|
||||
*finalURL = *r.c.base
|
||||
}
|
||||
finalURL.Path = p
|
||||
|
||||
@@ -468,8 +495,8 @@ func (r Request) finalURLTemplate() url.URL {
|
||||
segments := strings.Split(r.URL().Path, "/")
|
||||
groupIndex := 0
|
||||
index := 0
|
||||
if r.URL() != nil && r.baseURL != nil && strings.Contains(r.URL().Path, r.baseURL.Path) {
|
||||
groupIndex += len(strings.Split(r.baseURL.Path, "/"))
|
||||
if r.URL() != nil && r.c.base != nil && strings.Contains(r.URL().Path, r.c.base.Path) {
|
||||
groupIndex += len(strings.Split(r.c.base.Path, "/"))
|
||||
}
|
||||
if groupIndex >= len(segments) {
|
||||
return *url
|
||||
@@ -522,16 +549,16 @@ func (r Request) finalURLTemplate() url.URL {
|
||||
}
|
||||
|
||||
func (r *Request) tryThrottle() error {
|
||||
if r.throttle == nil {
|
||||
if r.rateLimiter == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
var err error
|
||||
if r.ctx != nil {
|
||||
err = r.throttle.Wait(r.ctx)
|
||||
err = r.rateLimiter.Wait(r.ctx)
|
||||
} else {
|
||||
r.throttle.Accept()
|
||||
r.rateLimiter.Accept()
|
||||
}
|
||||
|
||||
if latency := time.Since(now); latency > longThrottleLatency {
|
||||
@@ -544,27 +571,11 @@ func (r *Request) tryThrottle() error {
|
||||
// Watch attempts to begin watching the requested location.
|
||||
// Returns a watch.Interface, or an error.
|
||||
func (r *Request) Watch() (watch.Interface, error) {
|
||||
return r.WatchWithSpecificDecoders(
|
||||
func(body io.ReadCloser) streaming.Decoder {
|
||||
framer := r.serializers.Framer.NewFrameReader(body)
|
||||
return streaming.NewDecoder(framer, r.serializers.StreamingSerializer)
|
||||
},
|
||||
r.serializers.Decoder,
|
||||
)
|
||||
}
|
||||
|
||||
// WatchWithSpecificDecoders attempts to begin watching the requested location with a *different* decoder.
|
||||
// Turns out that you want one "standard" decoder for the watch event and one "personal" decoder for the content
|
||||
// Returns a watch.Interface, or an error.
|
||||
func (r *Request) WatchWithSpecificDecoders(wrapperDecoderFn func(io.ReadCloser) streaming.Decoder, embeddedDecoder runtime.Decoder) (watch.Interface, error) {
|
||||
// We specifically don't want to rate limit watches, so we
|
||||
// don't use r.throttle here.
|
||||
// don't use r.rateLimiter here.
|
||||
if r.err != nil {
|
||||
return nil, r.err
|
||||
}
|
||||
if r.serializers.Framer == nil {
|
||||
return nil, fmt.Errorf("watching resources is not possible with this client (content-type: %s)", r.content.ContentType)
|
||||
}
|
||||
|
||||
url := r.URL().String()
|
||||
req, err := http.NewRequest(r.verb, url, r.body)
|
||||
@@ -575,18 +586,18 @@ func (r *Request) WatchWithSpecificDecoders(wrapperDecoderFn func(io.ReadCloser)
|
||||
req = req.WithContext(r.ctx)
|
||||
}
|
||||
req.Header = r.headers
|
||||
client := r.client
|
||||
client := r.c.Client
|
||||
if client == nil {
|
||||
client = http.DefaultClient
|
||||
}
|
||||
r.backoffMgr.Sleep(r.backoffMgr.CalculateBackoff(r.URL()))
|
||||
r.backoff.Sleep(r.backoff.CalculateBackoff(r.URL()))
|
||||
resp, err := client.Do(req)
|
||||
updateURLMetrics(r, resp, err)
|
||||
if r.baseURL != nil {
|
||||
if r.c.base != nil {
|
||||
if err != nil {
|
||||
r.backoffMgr.UpdateBackoff(r.baseURL, err, 0)
|
||||
r.backoff.UpdateBackoff(r.c.base, err, 0)
|
||||
} else {
|
||||
r.backoffMgr.UpdateBackoff(r.baseURL, err, resp.StatusCode)
|
||||
r.backoff.UpdateBackoff(r.c.base, err, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
@@ -604,9 +615,22 @@ func (r *Request) WatchWithSpecificDecoders(wrapperDecoderFn func(io.ReadCloser)
|
||||
}
|
||||
return nil, fmt.Errorf("for request %s, got status: %v", url, resp.StatusCode)
|
||||
}
|
||||
wrapperDecoder := wrapperDecoderFn(resp.Body)
|
||||
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
mediaType, params, err := mime.ParseMediaType(contentType)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("Unexpected content type from the server: %q: %v", contentType, err)
|
||||
}
|
||||
objectDecoder, streamingSerializer, framer, err := r.c.content.Negotiator.StreamDecoder(mediaType, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frameReader := framer.NewFrameReader(resp.Body)
|
||||
watchEventDecoder := streaming.NewDecoder(frameReader, streamingSerializer)
|
||||
|
||||
return watch.NewStreamWatcher(
|
||||
restclientwatch.NewDecoder(wrapperDecoder, embeddedDecoder),
|
||||
restclientwatch.NewDecoder(watchEventDecoder, objectDecoder),
|
||||
// use 500 to indicate that the cause of the error is unknown - other error codes
|
||||
// are more specific to HTTP interactions, and set a reason
|
||||
errors.NewClientErrorReporter(http.StatusInternalServerError, r.verb, "ClientWatchDecoding"),
|
||||
@@ -617,8 +641,8 @@ func (r *Request) WatchWithSpecificDecoders(wrapperDecoderFn func(io.ReadCloser)
|
||||
// It also handles corner cases for incomplete/invalid request data.
|
||||
func updateURLMetrics(req *Request, resp *http.Response, err error) {
|
||||
url := "none"
|
||||
if req.baseURL != nil {
|
||||
url = req.baseURL.Host
|
||||
if req.c.base != nil {
|
||||
url = req.c.base.Host
|
||||
}
|
||||
|
||||
// Errors can be arbitrary strings. Unbound label cardinality is not suitable for a metric
|
||||
@@ -656,18 +680,18 @@ func (r *Request) Stream() (io.ReadCloser, error) {
|
||||
req = req.WithContext(r.ctx)
|
||||
}
|
||||
req.Header = r.headers
|
||||
client := r.client
|
||||
client := r.c.Client
|
||||
if client == nil {
|
||||
client = http.DefaultClient
|
||||
}
|
||||
r.backoffMgr.Sleep(r.backoffMgr.CalculateBackoff(r.URL()))
|
||||
r.backoff.Sleep(r.backoff.CalculateBackoff(r.URL()))
|
||||
resp, err := client.Do(req)
|
||||
updateURLMetrics(r, resp, err)
|
||||
if r.baseURL != nil {
|
||||
if r.c.base != nil {
|
||||
if err != nil {
|
||||
r.backoffMgr.UpdateBackoff(r.URL(), err, 0)
|
||||
r.backoff.UpdateBackoff(r.URL(), err, 0)
|
||||
} else {
|
||||
r.backoffMgr.UpdateBackoff(r.URL(), err, resp.StatusCode)
|
||||
r.backoff.UpdateBackoff(r.URL(), err, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
@@ -738,7 +762,7 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
||||
return err
|
||||
}
|
||||
|
||||
client := r.client
|
||||
client := r.c.Client
|
||||
if client == nil {
|
||||
client = http.DefaultClient
|
||||
}
|
||||
@@ -765,11 +789,11 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
||||
}
|
||||
req.Header = r.headers
|
||||
|
||||
r.backoffMgr.Sleep(r.backoffMgr.CalculateBackoff(r.URL()))
|
||||
r.backoff.Sleep(r.backoff.CalculateBackoff(r.URL()))
|
||||
if retries > 0 {
|
||||
// We are retrying the request that we already send to apiserver
|
||||
// at least once before.
|
||||
// This request should also be throttled with the client-internal throttler.
|
||||
// This request should also be throttled with the client-internal rate limiter.
|
||||
if err := r.tryThrottle(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -777,9 +801,9 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
||||
resp, err := client.Do(req)
|
||||
updateURLMetrics(r, resp, err)
|
||||
if err != nil {
|
||||
r.backoffMgr.UpdateBackoff(r.URL(), err, 0)
|
||||
r.backoff.UpdateBackoff(r.URL(), err, 0)
|
||||
} else {
|
||||
r.backoffMgr.UpdateBackoff(r.URL(), err, resp.StatusCode)
|
||||
r.backoff.UpdateBackoff(r.URL(), err, resp.StatusCode)
|
||||
}
|
||||
if err != nil {
|
||||
// "Connection reset by peer" is usually a transient error.
|
||||
@@ -822,7 +846,7 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
|
||||
}
|
||||
|
||||
klog.V(4).Infof("Got a Retry-After %ds response for attempt %d to %v", seconds, retries, url)
|
||||
r.backoffMgr.Sleep(time.Duration(seconds) * time.Second)
|
||||
r.backoff.Sleep(time.Duration(seconds) * time.Second)
|
||||
return false
|
||||
}
|
||||
fn(req, resp)
|
||||
@@ -908,14 +932,18 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
|
||||
glogBody("Response Body", body)
|
||||
|
||||
// verify the content type is accurate
|
||||
var decoder runtime.Decoder
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
decoder := r.serializers.Decoder
|
||||
if len(contentType) > 0 && (decoder == nil || (len(r.content.ContentType) > 0 && contentType != r.content.ContentType)) {
|
||||
if len(contentType) == 0 {
|
||||
contentType = r.c.content.ContentType
|
||||
}
|
||||
if len(contentType) > 0 {
|
||||
var err error
|
||||
mediaType, params, err := mime.ParseMediaType(contentType)
|
||||
if err != nil {
|
||||
return Result{err: errors.NewInternalError(err)}
|
||||
}
|
||||
decoder, err = r.serializers.RenegotiatedDecoder(mediaType, params)
|
||||
decoder, err = r.c.content.Negotiator.Decoder(mediaType, params)
|
||||
if err != nil {
|
||||
// if we fail to negotiate a decoder, treat this as an unstructured error
|
||||
switch {
|
||||
@@ -1035,7 +1063,7 @@ func (r *Request) newUnstructuredResponseError(body []byte, isTextResponse bool,
|
||||
}
|
||||
var groupResource schema.GroupResource
|
||||
if len(r.resource) > 0 {
|
||||
groupResource.Group = r.content.GroupVersion.Group
|
||||
groupResource.Group = r.c.content.GroupVersion.Group
|
||||
groupResource.Resource = r.resource
|
||||
}
|
||||
return errors.NewGenericServerResponse(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -180,7 +180,7 @@ func fakeScaleClient(t *testing.T) (ScalesGetter, []schema.GroupResource) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &http.Response{StatusCode: 200, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
case "PUT":
|
||||
decoder := codecs.UniversalDeserializer()
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
@@ -198,7 +198,7 @@ func fakeScaleClient(t *testing.T) (ScalesGetter, []schema.GroupResource) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &http.Response{StatusCode: 200, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
case "PATCH":
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
@@ -229,7 +229,7 @@ func fakeScaleClient(t *testing.T) (ScalesGetter, []schema.GroupResource) {
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid patch type")
|
||||
}
|
||||
return &http.Response{StatusCode: 200, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected request for URL %q with method %q", req.URL.String(), req.Method)
|
||||
}
|
||||
|
||||
2
tools/cache/index.go
vendored
2
tools/cache/index.go
vendored
@@ -56,7 +56,7 @@ type Indexer interface {
|
||||
type IndexFunc func(obj interface{}) ([]string, error)
|
||||
|
||||
// IndexFuncToKeyFuncAdapter adapts an indexFunc to a keyFunc. This is only useful if your index function returns
|
||||
// unique values for every object. This is conversion can create errors when more than one key is found. You
|
||||
// unique values for every object. This conversion can create errors when more than one key is found. You
|
||||
// should prefer to make proper key and index functions.
|
||||
func IndexFuncToKeyFuncAdapter(indexFunc IndexFunc) KeyFunc {
|
||||
return func(obj interface{}) (string, error) {
|
||||
|
||||
20
tools/cache/mutation_detector.go
vendored
20
tools/cache/mutation_detector.go
vendored
@@ -48,7 +48,7 @@ func NewCacheMutationDetector(name string) MutationDetector {
|
||||
return dummyMutationDetector{}
|
||||
}
|
||||
klog.Warningln("Mutation detector is enabled, this will result in memory leakage.")
|
||||
return &defaultCacheMutationDetector{name: name, period: 1 * time.Second}
|
||||
return &defaultCacheMutationDetector{name: name, period: 1 * time.Second, retainDuration: 2 * time.Minute}
|
||||
}
|
||||
|
||||
type dummyMutationDetector struct{}
|
||||
@@ -68,6 +68,10 @@ type defaultCacheMutationDetector struct {
|
||||
lock sync.Mutex
|
||||
cachedObjs []cacheObj
|
||||
|
||||
retainDuration time.Duration
|
||||
lastRotated time.Time
|
||||
retainedCachedObjs []cacheObj
|
||||
|
||||
// failureFunc is injectable for unit testing. If you don't have it, the process will panic.
|
||||
// This panic is intentional, since turning on this detection indicates you want a strong
|
||||
// failure signal. This failure is effectively a p0 bug and you can't trust process results
|
||||
@@ -84,6 +88,14 @@ type cacheObj struct {
|
||||
func (d *defaultCacheMutationDetector) Run(stopCh <-chan struct{}) {
|
||||
// we DON'T want protection from panics. If we're running this code, we want to die
|
||||
for {
|
||||
if d.lastRotated.IsZero() {
|
||||
d.lastRotated = time.Now()
|
||||
} else if time.Now().Sub(d.lastRotated) > d.retainDuration {
|
||||
d.retainedCachedObjs = d.cachedObjs
|
||||
d.cachedObjs = nil
|
||||
d.lastRotated = time.Now()
|
||||
}
|
||||
|
||||
d.CompareObjects()
|
||||
|
||||
select {
|
||||
@@ -120,6 +132,12 @@ func (d *defaultCacheMutationDetector) CompareObjects() {
|
||||
altered = true
|
||||
}
|
||||
}
|
||||
for i, obj := range d.retainedCachedObjs {
|
||||
if !reflect.DeepEqual(obj.cached, obj.copied) {
|
||||
fmt.Printf("CACHE %s[%d] ALTERED!\n%v\n", d.name, i, diff.ObjectGoPrintSideBySide(obj.cached, obj.copied))
|
||||
altered = true
|
||||
}
|
||||
}
|
||||
|
||||
if altered {
|
||||
msg := fmt.Sprintf("cache %s modified", d.name)
|
||||
|
||||
7
tools/cache/thread_safe_store.go
vendored
7
tools/cache/thread_safe_store.go
vendored
@@ -292,6 +292,13 @@ func (c *threadSafeMap) deleteFromIndices(obj interface{}, key string) {
|
||||
set := index[indexValue]
|
||||
if set != nil {
|
||||
set.Delete(key)
|
||||
|
||||
// If we don't delete the set when zero, indices with high cardinality
|
||||
// short lived resources can cause memory to increase over time from
|
||||
// unused empty sets. See `kubernetes/kubernetes/issues/84959`.
|
||||
if len(set) == 0 {
|
||||
delete(index, indexValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
92
tools/cache/thread_safe_store_test.go
vendored
Normal file
92
tools/cache/thread_safe_store_test.go
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright 2019 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 cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestThreadSafeStoreDeleteRemovesEmptySetsFromIndex(t *testing.T) {
|
||||
testIndexer := "testIndexer"
|
||||
|
||||
indexers := Indexers{
|
||||
testIndexer: func(obj interface{}) (strings []string, e error) {
|
||||
indexes := []string{obj.(string)}
|
||||
return indexes, nil
|
||||
},
|
||||
}
|
||||
|
||||
indices := Indices{}
|
||||
store := NewThreadSafeStore(indexers, indices).(*threadSafeMap)
|
||||
|
||||
testKey := "testKey"
|
||||
|
||||
store.Add(testKey, testKey)
|
||||
|
||||
// Assumption check, there should be a set for the `testKey` with one element in the added index
|
||||
set := store.indices[testIndexer][testKey]
|
||||
|
||||
if len(set) != 1 {
|
||||
t.Errorf("Initial assumption of index backing string set having 1 element failed. Actual elements: %d", len(set))
|
||||
return
|
||||
}
|
||||
|
||||
store.Delete(testKey)
|
||||
set, present := store.indices[testIndexer][testKey]
|
||||
|
||||
if present {
|
||||
t.Errorf("Index backing string set not deleted from index. Set length: %d", len(set))
|
||||
}
|
||||
}
|
||||
|
||||
func TestThreadSafeStoreAddKeepsNonEmptySetPostDeleteFromIndex(t *testing.T) {
|
||||
testIndexer := "testIndexer"
|
||||
testIndex := "testIndex"
|
||||
|
||||
indexers := Indexers{
|
||||
testIndexer: func(obj interface{}) (strings []string, e error) {
|
||||
indexes := []string{testIndex}
|
||||
return indexes, nil
|
||||
},
|
||||
}
|
||||
|
||||
indices := Indices{}
|
||||
store := NewThreadSafeStore(indexers, indices).(*threadSafeMap)
|
||||
|
||||
store.Add("retain", "retain")
|
||||
store.Add("delete", "delete")
|
||||
|
||||
// Assumption check, there should be a set for the `testIndex` with two elements
|
||||
set := store.indices[testIndexer][testIndex]
|
||||
|
||||
if len(set) != 2 {
|
||||
t.Errorf("Initial assumption of index backing string set having 2 elements failed. Actual elements: %d", len(set))
|
||||
return
|
||||
}
|
||||
|
||||
store.Delete("delete")
|
||||
set, present := store.indices[testIndexer][testIndex]
|
||||
|
||||
if !present {
|
||||
t.Errorf("Index backing string set erroneously deleted from index.")
|
||||
return
|
||||
}
|
||||
|
||||
if len(set) != 1 {
|
||||
t.Errorf("Index backing string set has incorrect length, expect 1. Set length: %d", len(set))
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,9 @@ func Convert_Slice_v1_NamedCluster_To_Map_string_To_Pointer_api_Cluster(in *[]Na
|
||||
if err := Convert_v1_Cluster_To_api_Cluster(&curr.Cluster, newCluster, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if *out == nil {
|
||||
*out = make(map[string]*api.Cluster)
|
||||
}
|
||||
if (*out)[curr.Name] == nil {
|
||||
(*out)[curr.Name] = newCluster
|
||||
} else {
|
||||
@@ -65,6 +68,9 @@ func Convert_Slice_v1_NamedAuthInfo_To_Map_string_To_Pointer_api_AuthInfo(in *[]
|
||||
if err := Convert_v1_AuthInfo_To_api_AuthInfo(&curr.AuthInfo, newAuthInfo, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if *out == nil {
|
||||
*out = make(map[string]*api.AuthInfo)
|
||||
}
|
||||
if (*out)[curr.Name] == nil {
|
||||
(*out)[curr.Name] = newAuthInfo
|
||||
} else {
|
||||
@@ -99,6 +105,9 @@ func Convert_Slice_v1_NamedContext_To_Map_string_To_Pointer_api_Context(in *[]Na
|
||||
if err := Convert_v1_Context_To_api_Context(&curr.Context, newContext, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if *out == nil {
|
||||
*out = make(map[string]*api.Context)
|
||||
}
|
||||
if (*out)[curr.Name] == nil {
|
||||
(*out)[curr.Name] = newContext
|
||||
} else {
|
||||
@@ -133,6 +142,9 @@ func Convert_Slice_v1_NamedExtension_To_Map_string_To_runtime_Object(in *[]Named
|
||||
if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&curr.Extension, &newExtension, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if *out == nil {
|
||||
*out = make(map[string]runtime.Object)
|
||||
}
|
||||
if (*out)[curr.Name] == nil {
|
||||
(*out)[curr.Name] = newExtension
|
||||
} else {
|
||||
|
||||
@@ -78,6 +78,32 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func TestNilOutMap(t *testing.T) {
|
||||
var fakeKubeconfigData = `apiVersion: v1
|
||||
kind: Config
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: UEhPTlkK
|
||||
server: https://1.1.1.1
|
||||
name: production
|
||||
contexts:
|
||||
- context:
|
||||
cluster: production
|
||||
user: production
|
||||
name: production
|
||||
current-context: production
|
||||
users:
|
||||
- name: production
|
||||
user:
|
||||
auth-provider:
|
||||
name: gcp`
|
||||
|
||||
_, _, err := clientcmdlatest.Codec.Decode([]byte(fakeKubeconfigData), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNonExistentCommandLineFile(t *testing.T) {
|
||||
loadingRules := ClientConfigLoadingRules{
|
||||
ExplicitPath: "bogus_file",
|
||||
|
||||
19
tools/events/doc.go
Normal file
19
tools/events/doc.go
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2019 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 events has all client logic for recording and reporting
|
||||
// "k8s.io/api/events/v1beta1".Event events.
|
||||
package events // import "k8s.io/client-go/tools/events"
|
||||
@@ -37,26 +37,27 @@ import (
|
||||
"k8s.io/client-go/tools/record"
|
||||
)
|
||||
|
||||
func createLockObject(t *testing.T, 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,
|
||||
}
|
||||
if record != nil {
|
||||
recordBytes, _ := json.Marshal(record)
|
||||
objectMeta.Annotations = map[string]string{
|
||||
rl.LeaderElectionRecordAnnotationKey: string(recordBytes),
|
||||
}
|
||||
}
|
||||
switch objectType {
|
||||
case "endpoints":
|
||||
recordBytes, _ := json.Marshal(record)
|
||||
objectMeta.Annotations = map[string]string{
|
||||
rl.LeaderElectionRecordAnnotationKey: string(recordBytes),
|
||||
}
|
||||
obj = &corev1.Endpoints{ObjectMeta: objectMeta}
|
||||
case "configmaps":
|
||||
recordBytes, _ := json.Marshal(record)
|
||||
objectMeta.Annotations = map[string]string{
|
||||
rl.LeaderElectionRecordAnnotationKey: string(recordBytes),
|
||||
}
|
||||
obj = &corev1.ConfigMap{ObjectMeta: objectMeta}
|
||||
case "leases":
|
||||
spec := rl.LeaderElectionRecordToLeaseSpec(&record)
|
||||
var spec coordinationv1.LeaseSpec
|
||||
if record != nil {
|
||||
spec = rl.LeaderElectionRecordToLeaseSpec(record)
|
||||
}
|
||||
obj = &coordinationv1.Lease{ObjectMeta: objectMeta, Spec: spec}
|
||||
default:
|
||||
t.Fatal("unexpected objType:" + objectType)
|
||||
@@ -108,13 +109,33 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
expectSuccess: true,
|
||||
outHolder: "baz",
|
||||
},
|
||||
{
|
||||
name: "acquire from object without annotations",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), nil), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
verb: "update",
|
||||
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 object",
|
||||
reactors: []Reactor{
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), rl.LeaderElectionRecord{}), nil
|
||||
return true, createLockObject(t, objectType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -135,7 +156,7 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, 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
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -158,7 +179,7 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, 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
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -180,7 +201,7 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, 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
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -195,7 +216,7 @@ func testTryAcquireOrRenew(t *testing.T, objectType string) {
|
||||
{
|
||||
verb: "get",
|
||||
reaction: func(action fakeclient.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, createLockObject(t, 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
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -421,7 +442,7 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -464,14 +485,14 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -485,7 +506,7 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -507,7 +528,7 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -528,7 +549,7 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -554,14 +575,14 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -575,7 +596,7 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -601,14 +622,14 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -626,14 +647,14 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -647,7 +668,7 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: rl.UnknownLeader}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -673,7 +694,7 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
return true, createLockObject(t, primaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -698,14 +719,14 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -723,14 +744,14 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "bing"}), nil
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -748,14 +769,14 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -769,7 +790,7 @@ func testTryAcquireOrRenewMultiLock(t *testing.T, objectType string) {
|
||||
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
|
||||
return true, createLockObject(t, secondaryType, action.GetNamespace(), action.(fakeclient.GetAction).GetName(), &rl.LeaderElectionRecord{HolderIdentity: "baz"}), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -82,6 +82,9 @@ func (el *EndpointsLock) Update(ler LeaderElectionRecord) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if el.e.Annotations == nil {
|
||||
el.e.Annotations = make(map[string]string)
|
||||
}
|
||||
el.e.Annotations[LeaderElectionRecordAnnotationKey] = string(recordBytes)
|
||||
el.e, err = el.Client.Endpoints(el.EndpointsMeta.Namespace).Update(el.e)
|
||||
return err
|
||||
|
||||
@@ -96,25 +96,24 @@ func (ll *LeaseLock) Identity() string {
|
||||
}
|
||||
|
||||
func LeaseSpecToLeaderElectionRecord(spec *coordinationv1.LeaseSpec) *LeaderElectionRecord {
|
||||
holderIdentity := ""
|
||||
var r LeaderElectionRecord
|
||||
if spec.HolderIdentity != nil {
|
||||
holderIdentity = *spec.HolderIdentity
|
||||
r.HolderIdentity = *spec.HolderIdentity
|
||||
}
|
||||
leaseDurationSeconds := 0
|
||||
if spec.LeaseDurationSeconds != nil {
|
||||
leaseDurationSeconds = int(*spec.LeaseDurationSeconds)
|
||||
r.LeaseDurationSeconds = int(*spec.LeaseDurationSeconds)
|
||||
}
|
||||
leaseTransitions := 0
|
||||
if spec.LeaseTransitions != nil {
|
||||
leaseTransitions = int(*spec.LeaseTransitions)
|
||||
r.LeaderTransitions = int(*spec.LeaseTransitions)
|
||||
}
|
||||
return &LeaderElectionRecord{
|
||||
HolderIdentity: holderIdentity,
|
||||
LeaseDurationSeconds: leaseDurationSeconds,
|
||||
AcquireTime: metav1.Time{spec.AcquireTime.Time},
|
||||
RenewTime: metav1.Time{spec.RenewTime.Time},
|
||||
LeaderTransitions: leaseTransitions,
|
||||
if spec.AcquireTime != nil {
|
||||
r.AcquireTime = metav1.Time{spec.AcquireTime.Time}
|
||||
}
|
||||
if spec.RenewTime != nil {
|
||||
r.RenewTime = metav1.Time{spec.RenewTime.Time}
|
||||
}
|
||||
return &r
|
||||
|
||||
}
|
||||
|
||||
func LeaderElectionRecordToLeaseSpec(ler *LeaderElectionRecord) coordinationv1.LeaseSpec {
|
||||
|
||||
@@ -77,6 +77,7 @@ func (p *ListPager) List(ctx context.Context, options metav1.ListOptions) (runti
|
||||
if options.Limit == 0 {
|
||||
options.Limit = p.PageSize
|
||||
}
|
||||
requestedResourceVersion := options.ResourceVersion
|
||||
var list *metainternalversion.List
|
||||
for {
|
||||
select {
|
||||
@@ -87,12 +88,18 @@ func (p *ListPager) List(ctx context.Context, options metav1.ListOptions) (runti
|
||||
|
||||
obj, err := p.PageFn(ctx, options)
|
||||
if err != nil {
|
||||
if !errors.IsResourceExpired(err) || !p.FullListIfExpired {
|
||||
// Only fallback to full list if an "Expired" errors is returned, FullListIfExpired is true, and
|
||||
// the "Expired" error occurred in page 2 or later (since full list is intended to prevent a pager.List from
|
||||
// failing when the resource versions is established by the first page request falls out of the compaction
|
||||
// during the subsequent list requests).
|
||||
if !errors.IsResourceExpired(err) || !p.FullListIfExpired || options.Continue == "" {
|
||||
return nil, err
|
||||
}
|
||||
// the list expired while we were processing, fall back to a full list
|
||||
// the list expired while we were processing, fall back to a full list at
|
||||
// the requested ResourceVersion.
|
||||
options.Limit = 0
|
||||
options.Continue = ""
|
||||
options.ResourceVersion = requestedResourceVersion
|
||||
return p.PageFn(ctx, options)
|
||||
}
|
||||
m, err := meta.ListAccessor(obj)
|
||||
@@ -125,6 +132,10 @@ func (p *ListPager) List(ctx context.Context, options metav1.ListOptions) (runti
|
||||
|
||||
// set the next loop up
|
||||
options.Continue = m.GetContinue()
|
||||
// Clear the ResourceVersion on the subsequent List calls to avoid the
|
||||
// `specifying resource version is not allowed when using continue` error.
|
||||
// See https://github.com/kubernetes/kubernetes/issues/85221#issuecomment-553748143.
|
||||
options.ResourceVersion = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,10 @@ func (p *testPager) PagedList(ctx context.Context, options metav1.ListOptions) (
|
||||
p.t.Errorf("invariant violated, expected limit %d and continue %s, got %#v", p.expectPage, expectedContinue, options)
|
||||
return nil, fmt.Errorf("invariant violated")
|
||||
}
|
||||
if options.Continue != "" && options.ResourceVersion != "" {
|
||||
p.t.Errorf("invariant violated, specifying resource version (%s) is not allowed when using continue (%s).", options.ResourceVersion, options.Continue)
|
||||
return nil, fmt.Errorf("invariant violated")
|
||||
}
|
||||
var list metainternalversion.List
|
||||
total := options.Limit
|
||||
if total == 0 {
|
||||
@@ -181,6 +185,12 @@ func TestListPager_List(t *testing.T) {
|
||||
args: args{},
|
||||
want: list(21, "rv:20"),
|
||||
},
|
||||
{
|
||||
name: "two pages with resourceVersion",
|
||||
fields: fields{PageSize: 10, PageFn: (&testPager{t: t, expectPage: 10, remaining: 11, rv: "rv:20"}).PagedList},
|
||||
args: args{options: metav1.ListOptions{ResourceVersion: "rv:10"}},
|
||||
want: list(11, "rv:20"),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
@@ -14,5 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package record has all client logic for recording and reporting events.
|
||||
// Package record has all client logic for recording and reporting
|
||||
// "k8s.io/api/core/v1".Event events.
|
||||
package record // import "k8s.io/client-go/tools/record"
|
||||
|
||||
@@ -132,14 +132,14 @@ type EventBroadcaster interface {
|
||||
Shutdown()
|
||||
}
|
||||
|
||||
// EventRecorderAdapter is a wrapper around EventRecorder implementing the
|
||||
// new EventRecorder interface.
|
||||
// EventRecorderAdapter is a wrapper around a "k8s.io/client-go/tools/record".EventRecorder
|
||||
// implementing the new "k8s.io/client-go/tools/events".EventRecorder interface.
|
||||
type EventRecorderAdapter struct {
|
||||
recorder EventRecorder
|
||||
}
|
||||
|
||||
// NewEventRecorderAdapter returns an adapter implementing new EventRecorder
|
||||
// interface.
|
||||
// NewEventRecorderAdapter returns an adapter implementing the new
|
||||
// "k8s.io/client-go/tools/events".EventRecorder interface.
|
||||
func NewEventRecorderAdapter(recorder EventRecorder) *EventRecorderAdapter {
|
||||
return &EventRecorderAdapter{
|
||||
recorder: recorder,
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package cert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
@@ -59,3 +60,14 @@ func ParseCertsPEM(pemCerts []byte) ([]*x509.Certificate, error) {
|
||||
}
|
||||
return certs, nil
|
||||
}
|
||||
|
||||
// EncodeCertificates returns the PEM-encoded byte array that represents by the specified certs.
|
||||
func EncodeCertificates(certs ...*x509.Certificate) ([]byte, error) {
|
||||
b := bytes.Buffer{}
|
||||
for _, cert := range certs {
|
||||
if err := pem.Encode(&b, &pem.Block{Type: CertificateBlockType, Bytes: cert.Raw}); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
}
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
102
util/cert/server_inspection.go
Normal file
102
util/cert/server_inspection.go
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright 2019 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 cert
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetClientCANames gets the CA names for client certs that a server accepts. This is useful when inspecting the
|
||||
// state of particular servers. apiHost is "host:port"
|
||||
func GetClientCANames(apiHost string) ([]string, error) {
|
||||
// when we run this the second time, we know which one we are expecting
|
||||
acceptableCAs := []string{}
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: true, // this is insecure to always get to the GetClientCertificate
|
||||
GetClientCertificate: func(hello *tls.CertificateRequestInfo) (*tls.Certificate, error) {
|
||||
acceptableCAs = []string{}
|
||||
for _, curr := range hello.AcceptableCAs {
|
||||
acceptableCAs = append(acceptableCAs, string(curr))
|
||||
}
|
||||
return &tls.Certificate{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
conn, err := tls.Dial("tcp", apiHost, tlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := conn.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return acceptableCAs, nil
|
||||
}
|
||||
|
||||
// GetClientCANamesForURL is GetClientCANames against a URL string like we use in kubeconfigs
|
||||
func GetClientCANamesForURL(kubeConfigURL string) ([]string, error) {
|
||||
apiserverURL, err := url.Parse(kubeConfigURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetClientCANames(apiserverURL.Host)
|
||||
}
|
||||
|
||||
// GetServingCertificates returns the x509 certs used by a server as certificates and pem encoded bytes.
|
||||
// The serverName is optional for specifying a different name to get SNI certificates. apiHost is "host:port"
|
||||
func GetServingCertificates(apiHost, serverName string) ([]*x509.Certificate, [][]byte, error) {
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: true, // this is insecure so that we always get connected
|
||||
}
|
||||
// if a name is specified for SNI, set it.
|
||||
if len(serverName) > 0 {
|
||||
tlsConfig.ServerName = serverName
|
||||
}
|
||||
|
||||
conn, err := tls.Dial("tcp", apiHost, tlsConfig)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err = conn.Close(); err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to close connection : %v", err)
|
||||
}
|
||||
|
||||
peerCerts := conn.ConnectionState().PeerCertificates
|
||||
peerCertBytes := [][]byte{}
|
||||
for _, a := range peerCerts {
|
||||
actualCert, err := EncodeCertificates(a)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
peerCertBytes = append(peerCertBytes, []byte(strings.TrimSpace(string(actualCert))))
|
||||
}
|
||||
|
||||
return peerCerts, peerCertBytes, err
|
||||
}
|
||||
|
||||
// GetServingCertificatesForURL is GetServingCertificates against a URL string like we use in kubeconfigs
|
||||
func GetServingCertificatesForURL(kubeConfigURL, serverName string) ([]*x509.Certificate, [][]byte, error) {
|
||||
apiserverURL, err := url.Parse(kubeConfigURL)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return GetServingCertificates(apiserverURL.Host, serverName)
|
||||
}
|
||||
@@ -113,8 +113,17 @@ type Config struct {
|
||||
// quickly replaced with a unique cert/key pair.
|
||||
BootstrapKeyPEM []byte
|
||||
// CertificateExpiration will record a metric that shows the remaining
|
||||
// lifetime of the certificate.
|
||||
// lifetime of the certificate. This metric is a gauge because only the
|
||||
// current cert expiry time is really useful. Reading this metric at any
|
||||
// time simply gives the next expiration date, no need to keep some
|
||||
// history (histogram) of all previous expiry dates.
|
||||
CertificateExpiration Gauge
|
||||
// CertificateRotation will record a metric showing the time in seconds
|
||||
// that certificates lived before being rotated. This metric is a histogram
|
||||
// because there is value in keeping a history of rotation cadences. It
|
||||
// allows one to setup monitoring and alerting of unexpected rotation
|
||||
// behavior and track trends in rotation frequency.
|
||||
CertificateRotation Histogram
|
||||
}
|
||||
|
||||
// Store is responsible for getting and updating the current certificate.
|
||||
@@ -139,6 +148,12 @@ type Gauge interface {
|
||||
Set(float64)
|
||||
}
|
||||
|
||||
// Histogram will record the time a rotated certificate was used before being
|
||||
// rotated.
|
||||
type Histogram interface {
|
||||
Observe(float64)
|
||||
}
|
||||
|
||||
// NoCertKeyError indicates there is no cert/key currently available.
|
||||
type NoCertKeyError string
|
||||
|
||||
@@ -163,6 +178,7 @@ type manager struct {
|
||||
certStore Store
|
||||
|
||||
certificateExpiration Gauge
|
||||
certificateRotation Histogram
|
||||
|
||||
// the following variables must only be accessed under certAccessLock
|
||||
certAccessLock sync.RWMutex
|
||||
@@ -174,6 +190,9 @@ type manager struct {
|
||||
clientFn CSRClientFunc
|
||||
stopCh chan struct{}
|
||||
stopped bool
|
||||
|
||||
// Set to time.Now but can be stubbed out for testing
|
||||
now func() time.Time
|
||||
}
|
||||
|
||||
// NewManager returns a new certificate manager. A certificate manager is
|
||||
@@ -203,6 +222,8 @@ func NewManager(config *Config) (Manager, error) {
|
||||
cert: cert,
|
||||
forceRotation: forceRotation,
|
||||
certificateExpiration: config.CertificateExpiration,
|
||||
certificateRotation: config.CertificateRotation,
|
||||
now: time.Now,
|
||||
}
|
||||
|
||||
return &m, nil
|
||||
@@ -215,7 +236,7 @@ func NewManager(config *Config) (Manager, error) {
|
||||
func (m *manager) Current() *tls.Certificate {
|
||||
m.certAccessLock.RLock()
|
||||
defer m.certAccessLock.RUnlock()
|
||||
if m.cert != nil && m.cert.Leaf != nil && time.Now().After(m.cert.Leaf.NotAfter) {
|
||||
if m.cert != nil && m.cert.Leaf != nil && m.now().After(m.cert.Leaf.NotAfter) {
|
||||
klog.V(2).Infof("Current certificate is expired.")
|
||||
return nil
|
||||
}
|
||||
@@ -256,7 +277,7 @@ func (m *manager) Start() {
|
||||
templateChanged := make(chan struct{})
|
||||
go wait.Until(func() {
|
||||
deadline := m.nextRotationDeadline()
|
||||
if sleepInterval := deadline.Sub(time.Now()); sleepInterval > 0 {
|
||||
if sleepInterval := deadline.Sub(m.now()); sleepInterval > 0 {
|
||||
klog.V(2).Infof("Waiting %v for next certificate rotation", sleepInterval)
|
||||
|
||||
timer := time.NewTimer(sleepInterval)
|
||||
@@ -421,7 +442,10 @@ func (m *manager) rotateCerts() (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
m.updateCached(cert)
|
||||
if old := m.updateCached(cert); old != nil && m.certificateRotation != nil {
|
||||
m.certificateRotation.Observe(m.now().Sub(old.Leaf.NotBefore).Seconds())
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -490,14 +514,14 @@ func (m *manager) nextRotationDeadline() time.Time {
|
||||
// forceRotation is not protected by locks
|
||||
if m.forceRotation {
|
||||
m.forceRotation = false
|
||||
return time.Now()
|
||||
return m.now()
|
||||
}
|
||||
|
||||
m.certAccessLock.RLock()
|
||||
defer m.certAccessLock.RUnlock()
|
||||
|
||||
if !m.certSatisfiesTemplateLocked() {
|
||||
return time.Now()
|
||||
return m.now()
|
||||
}
|
||||
|
||||
notAfter := m.cert.Leaf.NotAfter
|
||||
@@ -523,13 +547,15 @@ var jitteryDuration = func(totalDuration float64) time.Duration {
|
||||
return wait.Jitter(time.Duration(totalDuration), 0.2) - time.Duration(totalDuration*0.3)
|
||||
}
|
||||
|
||||
// updateCached sets the most recent retrieved cert. It also sets the server
|
||||
// as assumed healthy.
|
||||
func (m *manager) updateCached(cert *tls.Certificate) {
|
||||
// updateCached sets the most recent retrieved cert and returns the old cert.
|
||||
// It also sets the server as assumed healthy.
|
||||
func (m *manager) updateCached(cert *tls.Certificate) *tls.Certificate {
|
||||
m.certAccessLock.Lock()
|
||||
defer m.certAccessLock.Unlock()
|
||||
m.serverHealth = true
|
||||
old := m.cert
|
||||
m.cert = cert
|
||||
return old
|
||||
}
|
||||
|
||||
// updateServerError takes an error returned by the server and infers
|
||||
|
||||
@@ -163,12 +163,17 @@ func TestNewManagerNoRotation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type gaugeMock struct {
|
||||
type metricMock struct {
|
||||
calls int
|
||||
lastValue float64
|
||||
}
|
||||
|
||||
func (g *gaugeMock) Set(v float64) {
|
||||
func (g *metricMock) Set(v float64) {
|
||||
g.calls++
|
||||
g.lastValue = v
|
||||
}
|
||||
|
||||
func (g *metricMock) Observe(v float64) {
|
||||
g.calls++
|
||||
g.lastValue = v
|
||||
}
|
||||
@@ -195,7 +200,7 @@ func TestSetRotationDeadline(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
g := gaugeMock{}
|
||||
g := metricMock{}
|
||||
m := manager{
|
||||
cert: &tls.Certificate{
|
||||
Leaf: &x509.Certificate{
|
||||
@@ -206,6 +211,7 @@ func TestSetRotationDeadline(t *testing.T) {
|
||||
getTemplate: func() *x509.CertificateRequest { return &x509.CertificateRequest{} },
|
||||
usages: []certificates.KeyUsage{},
|
||||
certificateExpiration: &g,
|
||||
now: func() time.Time { return now },
|
||||
}
|
||||
jitteryDuration = func(float64) time.Duration { return time.Duration(float64(tc.notAfter.Sub(tc.notBefore)) * 0.7) }
|
||||
lowerBound := tc.notBefore.Add(time.Duration(float64(tc.notAfter.Sub(tc.notBefore)) * 0.7))
|
||||
@@ -383,6 +389,7 @@ func TestCertSatisfiesTemplate(t *testing.T) {
|
||||
m := manager{
|
||||
cert: tlsCert,
|
||||
getTemplate: func() *x509.CertificateRequest { return tc.template },
|
||||
now: time.Now,
|
||||
}
|
||||
|
||||
result := m.certSatisfiesTemplate()
|
||||
@@ -407,6 +414,7 @@ func TestRotateCertCreateCSRError(t *testing.T) {
|
||||
clientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return fakeClient{failureType: createError}, nil
|
||||
},
|
||||
now: func() time.Time { return now },
|
||||
}
|
||||
|
||||
if success, err := m.rotateCerts(); success {
|
||||
@@ -430,6 +438,7 @@ func TestRotateCertWaitingForResultError(t *testing.T) {
|
||||
clientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return fakeClient{failureType: watchError}, nil
|
||||
},
|
||||
now: func() time.Time { return now },
|
||||
}
|
||||
|
||||
defer func(t time.Duration) { certificateWaitTimeout = t }(certificateWaitTimeout)
|
||||
@@ -945,6 +954,40 @@ func TestServerHealth(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRotationLogsDuration(t *testing.T) {
|
||||
h := metricMock{}
|
||||
now := time.Now()
|
||||
certIss := now.Add(-2 * time.Hour)
|
||||
m := manager{
|
||||
cert: &tls.Certificate{
|
||||
Leaf: &x509.Certificate{
|
||||
NotBefore: certIss,
|
||||
NotAfter: now.Add(-1 * time.Hour),
|
||||
},
|
||||
},
|
||||
certStore: &fakeStore{cert: expiredStoreCertData.certificate},
|
||||
getTemplate: func() *x509.CertificateRequest { return &x509.CertificateRequest{} },
|
||||
clientFn: func(_ *tls.Certificate) (certificatesclient.CertificateSigningRequestInterface, error) {
|
||||
return &fakeClient{
|
||||
certificatePEM: apiServerCertData.certificatePEM,
|
||||
}, nil
|
||||
},
|
||||
certificateRotation: &h,
|
||||
now: func() time.Time { return now },
|
||||
}
|
||||
ok, err := m.rotateCerts()
|
||||
if err != nil || !ok {
|
||||
t.Errorf("failed to rotate certs: %v", err)
|
||||
}
|
||||
if h.calls != 1 {
|
||||
t.Errorf("rotation metric was not called")
|
||||
}
|
||||
if h.lastValue != now.Sub(certIss).Seconds() {
|
||||
t.Errorf("rotation metric did not record the right value got: %f; want %f", h.lastValue, now.Sub(certIss).Seconds())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type fakeClientFailureType int
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user