Adds bool to force non-aggregated discovery

Kubernetes-commit: a84d877310ba5cf9237c8e8e3218229c202d3a1e
This commit is contained in:
Sean Sullivan 2022-11-09 12:30:05 -08:00 committed by Kubernetes Publisher
parent c8ffed3108
commit 3ac73ea2c8
8 changed files with 79 additions and 4 deletions

View File

@ -277,6 +277,12 @@ func (d *CachedDiscoveryClient) Invalidate() {
} }
} }
// WithLegacy returns current cached discovery client;
// current client does not support legacy-only discovery.
func (d *CachedDiscoveryClient) WithLegacy() discovery.DiscoveryInterface {
return d
}
// NewCachedDiscoveryClientForConfig creates a new DiscoveryClient for the given config, and wraps // NewCachedDiscoveryClientForConfig creates a new DiscoveryClient for the given config, and wraps
// the created client in a CachedDiscoveryClient. The provided configuration is updated with a // the created client in a CachedDiscoveryClient. The provided configuration is updated with a
// custom transport that understands cache responses. // custom transport that understands cache responses.

View File

@ -786,6 +786,10 @@ func (d *fakeDiscoveryClient) OpenAPIV3() openapi.Client {
panic("unimplemented") panic("unimplemented")
} }
func (d *fakeDiscoveryClient) WithLegacy() discovery.DiscoveryInterface {
panic("unimplemented")
}
func groupNamesFromList(groups *metav1.APIGroupList) []string { func groupNamesFromList(groups *metav1.APIGroupList) []string {
result := []string{} result := []string{}
for _, group := range groups.Groups { for _, group := range groups.Groups {

View File

@ -279,6 +279,12 @@ func (d *memCacheClient) serverResourcesForGroupVersion(groupVersion string) (*m
return r, nil return r, nil
} }
// WithLegacy returns current memory-cached discovery client;
// current client does not support legacy-only discovery.
func (d *memCacheClient) WithLegacy() discovery.DiscoveryInterface {
return d
}
// NewMemCacheClient creates a new CachedDiscoveryInterface which caches // NewMemCacheClient creates a new CachedDiscoveryInterface which caches
// discovery information in memory and will stay up-to-date if Invalidate is // discovery information in memory and will stay up-to-date if Invalidate is
// called with regularity. // called with regularity.

View File

@ -74,6 +74,10 @@ type DiscoveryInterface interface {
ServerVersionInterface ServerVersionInterface
OpenAPISchemaInterface OpenAPISchemaInterface
OpenAPIV3SchemaInterface OpenAPIV3SchemaInterface
// Returns copy of current discovery client that will only
// receive the legacy discovery format, or pointer to current
// discovery client if it does not support legacy-only discovery.
WithLegacy() DiscoveryInterface
} }
// AggregatedDiscoveryInterface extends DiscoveryInterface to include a method to possibly // AggregatedDiscoveryInterface extends DiscoveryInterface to include a method to possibly
@ -154,6 +158,8 @@ type DiscoveryClient struct {
restClient restclient.Interface restClient restclient.Interface
LegacyPrefix string LegacyPrefix string
// Forces the client to request only "unaggregated" (legacy) discovery.
UseLegacyDiscovery bool
} }
var _ AggregatedDiscoveryInterface = &DiscoveryClient{} var _ AggregatedDiscoveryInterface = &DiscoveryClient{}
@ -213,10 +219,14 @@ func (d *DiscoveryClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[s
// possible for the resource map to be nil if the server returned // possible for the resource map to be nil if the server returned
// the unaggregated discovery. // the unaggregated discovery.
func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) {
accept := acceptDiscoveryFormats
if d.UseLegacyDiscovery {
accept = AcceptV1
}
var responseContentType string var responseContentType string
body, err := d.restClient.Get(). body, err := d.restClient.Get().
AbsPath("/api"). AbsPath("/api").
SetHeader("Accept", acceptDiscoveryFormats). SetHeader("Accept", accept).
Do(context.TODO()). Do(context.TODO()).
ContentType(&responseContentType). ContentType(&responseContentType).
Raw() Raw()
@ -262,10 +272,14 @@ func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.Gro
// discovery resources. The returned groups will always exist, but the // discovery resources. The returned groups will always exist, but the
// resources map may be nil. // resources map may be nil.
func (d *DiscoveryClient) downloadAPIs() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { func (d *DiscoveryClient) downloadAPIs() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) {
accept := acceptDiscoveryFormats
if d.UseLegacyDiscovery {
accept = AcceptV1
}
var responseContentType string var responseContentType string
body, err := d.restClient.Get(). body, err := d.restClient.Get().
AbsPath("/apis"). AbsPath("/apis").
SetHeader("Accept", acceptDiscoveryFormats). SetHeader("Accept", accept).
Do(context.TODO()). Do(context.TODO()).
ContentType(&responseContentType). ContentType(&responseContentType).
Raw() Raw()
@ -590,6 +604,14 @@ func (d *DiscoveryClient) OpenAPIV3() openapi.Client {
return openapi.NewClient(d.restClient) return openapi.NewClient(d.restClient)
} }
// WithLegacy returns copy of current discovery client that will only
// receive the legacy discovery format.
func (d *DiscoveryClient) WithLegacy() DiscoveryInterface {
client := *d
client.UseLegacyDiscovery = true
return &client
}
// withRetries retries the given recovery function in case the groups supported by the server change after ServerGroup() returns. // withRetries retries the given recovery function in case the groups supported by the server change after ServerGroup() returns.
func withRetries(maxRetries int, f func() ([]*metav1.APIGroup, []*metav1.APIResourceList, error)) ([]*metav1.APIGroup, []*metav1.APIResourceList, error) { func withRetries(maxRetries int, f func() ([]*metav1.APIGroup, []*metav1.APIResourceList, error)) ([]*metav1.APIGroup, []*metav1.APIResourceList, error) {
var result []*metav1.APIResourceList var result []*metav1.APIResourceList
@ -654,7 +676,7 @@ func NewDiscoveryClientForConfigAndClient(c *restclient.Config, httpClient *http
return nil, err return nil, err
} }
client, err := restclient.UnversionedRESTClientForConfigAndClient(&config, httpClient) client, err := restclient.UnversionedRESTClientForConfigAndClient(&config, httpClient)
return &DiscoveryClient{restClient: client, LegacyPrefix: "/api"}, err return &DiscoveryClient{restClient: client, LegacyPrefix: "/api", UseLegacyDiscovery: false}, err
} }
// NewDiscoveryClientForConfigOrDie creates a new DiscoveryClient for the given config. If // NewDiscoveryClientForConfigOrDie creates a new DiscoveryClient for the given config. If
@ -670,7 +692,7 @@ func NewDiscoveryClientForConfigOrDie(c *restclient.Config) *DiscoveryClient {
// NewDiscoveryClient returns a new DiscoveryClient for the given RESTClient. // NewDiscoveryClient returns a new DiscoveryClient for the given RESTClient.
func NewDiscoveryClient(c restclient.Interface) *DiscoveryClient { func NewDiscoveryClient(c restclient.Interface) *DiscoveryClient {
return &DiscoveryClient{restClient: c, LegacyPrefix: "/api"} return &DiscoveryClient{restClient: c, LegacyPrefix: "/api", UseLegacyDiscovery: false}
} }
// RESTClient returns a RESTClient that is used to communicate // RESTClient returns a RESTClient that is used to communicate

View File

@ -2297,6 +2297,26 @@ func TestAggregatedServerPreferredResources(t *testing.T) {
} }
} }
func TestUseLegacyDiscovery(t *testing.T) {
// Default client sends aggregated discovery accept format (first) as well as legacy format.
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
acceptHeader := req.Header.Get("Accept")
assert.Equal(t, acceptDiscoveryFormats, acceptHeader)
}))
defer server.Close()
client := NewDiscoveryClientForConfigOrDie(&restclient.Config{Host: server.URL})
client.ServerGroups()
// When "UseLegacyDiscovery" field is set, only the legacy discovery format is requested.
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
acceptHeader := req.Header.Get("Accept")
assert.Equal(t, AcceptV1, acceptHeader)
}))
defer server.Close()
client = NewDiscoveryClientForConfigOrDie(&restclient.Config{Host: server.URL})
client.UseLegacyDiscovery = true
client.ServerGroups()
}
func groupNames(groups []*metav1.APIGroup) []string { func groupNames(groups []*metav1.APIGroup) []string {
result := []string{} result := []string{}
for _, group := range groups { for _, group := range groups {

View File

@ -26,6 +26,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/version" "k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/discovery"
"k8s.io/client-go/openapi" "k8s.io/client-go/openapi"
kubeversion "k8s.io/client-go/pkg/version" kubeversion "k8s.io/client-go/pkg/version"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
@ -164,3 +165,7 @@ func (c *FakeDiscovery) OpenAPIV3() openapi.Client {
func (c *FakeDiscovery) RESTClient() restclient.Interface { func (c *FakeDiscovery) RESTClient() restclient.Interface {
return nil return nil
} }
func (c *FakeDiscovery) WithLegacy() discovery.DiscoveryInterface {
panic("unimplemented")
}

View File

@ -422,6 +422,10 @@ func (c *fakeFailingDiscovery) OpenAPIV3() openapi.Client {
panic("implement me") panic("implement me")
} }
func (c *fakeFailingDiscovery) WithLegacy() DiscoveryInterface {
panic("implement me")
}
type fakeCachedDiscoveryInterface struct { type fakeCachedDiscoveryInterface struct {
invalidateCalls int invalidateCalls int
fresh bool fresh bool
@ -499,6 +503,10 @@ func (c *fakeCachedDiscoveryInterface) OpenAPIV3() openapi.Client {
panic("implement me") panic("implement me")
} }
func (c *fakeCachedDiscoveryInterface) WithLegacy() DiscoveryInterface {
panic("implement me")
}
var ( var (
aGroup = metav1.APIGroup{ aGroup = metav1.APIGroup{
Name: "a", Name: "a",

View File

@ -362,6 +362,10 @@ func (c *fakeDiscoveryClient) OpenAPIV3() openapi.Client {
panic("implement me") panic("implement me")
} }
func (c *fakeDiscoveryClient) WithLegacy() discovery.DiscoveryInterface {
panic("implement me")
}
type fakeCachedDiscoveryClient struct { type fakeCachedDiscoveryClient struct {
discovery.DiscoveryInterface discovery.DiscoveryInterface
freshHandler func() bool freshHandler func() bool