diff --git a/staging/src/k8s.io/client-go/applyconfigurations/meta/v1/unstructured.go b/staging/src/k8s.io/client-go/applyconfigurations/meta/v1/unstructured.go index 222772ad720..e73dc9d03a8 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/meta/v1/unstructured.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/meta/v1/unstructured.go @@ -19,14 +19,8 @@ type UnstructuredExtractor interface { ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error) } -//// objectTypeCache is a cache of typed.ParseableTypes -//type objectTypeCache interface { -// objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error) -//} - -// objectTypeCache is a objectTypeCache that does no caching -// (i.e. it downloads the OpenAPISchema every time) -// Useful during the proof-of-concept stage until we agree on a caching solution. +// objectTypeCache caches the GVKParser in order to prevent from having to repeatedly +// parse the models from the open API schema when the schema itself changes infrequently. type objectTypeCache struct { // TODO: lock this? discoveryClient discovery.DiscoveryInterface @@ -35,7 +29,6 @@ type objectTypeCache struct { // objectTypeForGVK retrieves the typed.ParseableType for a given gvk from the cache func (c *objectTypeCache) objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error) { - if !c.discoveryClient.HasOpenAPISchemaChanged() && c.gvkParser != nil { // cache hit fmt.Println("cache hit") diff --git a/staging/src/k8s.io/client-go/discovery/cached/disk/cached_discovery.go b/staging/src/k8s.io/client-go/discovery/cached/disk/cached_discovery.go index 61acab9709a..c44bdd02218 100644 --- a/staging/src/k8s.io/client-go/discovery/cached/disk/cached_discovery.go +++ b/staging/src/k8s.io/client-go/discovery/cached/disk/cached_discovery.go @@ -240,6 +240,7 @@ func (d *CachedDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) { return d.delegate.OpenAPISchema() } +// HasOpenAPISchemaChanged checks wether the open API schema being served is cached or not. func (d *CachedDiscoveryClient) HasOpenAPISchemaChanged() bool { return d.delegate.HasOpenAPISchemaChanged() } diff --git a/staging/src/k8s.io/client-go/discovery/discovery_client.go b/staging/src/k8s.io/client-go/discovery/discovery_client.go index 87f79dc46e0..5eb16d1d455 100644 --- a/staging/src/k8s.io/client-go/discovery/discovery_client.go +++ b/staging/src/k8s.io/client-go/discovery/discovery_client.go @@ -122,11 +122,14 @@ type ServerVersionInterface interface { ServerVersion() (*version.Info, error) } -// OpenAPISchemaInterface has a method to retrieve the open API schema. +// OpenAPISchemaInterface has a method to retrieve the open API schema +// and a method to check whether the open API schema has changed. type OpenAPISchemaInterface interface { // OpenAPISchema retrieves and parses the swagger API schema the server supports. OpenAPISchema() (*openapi_v2.Document, error) + // HasOpenAPISchema changed checks whether the API schema being served + // by the apiserver is cached (and thus has not changed). HasOpenAPISchemaChanged() bool } @@ -423,6 +426,8 @@ func (d *DiscoveryClient) ServerVersion() (*version.Info, error) { return &info, nil } +// HasOpenAPISchemaChanged checks whether a HEAD request to openapi endpoint returns +// a 304 StatusNotModified meaning it has not changed. func (d *DiscoveryClient) HasOpenAPISchemaChanged() bool { result := d.restClient.Verb("HEAD").AbsPath("/openapi/v2").SetHeader("If-None-Match", d.etag).SetHeader("Accept", mimePb).Do(context.TODO()) var status int diff --git a/staging/src/k8s.io/client-go/discovery/fake/discovery.go b/staging/src/k8s.io/client-go/discovery/fake/discovery.go index fc89bed0f80..9ed51dc7789 100644 --- a/staging/src/k8s.io/client-go/discovery/fake/discovery.go +++ b/staging/src/k8s.io/client-go/discovery/fake/discovery.go @@ -153,6 +153,7 @@ func (c *FakeDiscovery) OpenAPISchema() (*openapi_v2.Document, error) { return &openapi_v2.Document{}, nil } +// HasOpenAPISchemaChanged checks wether the open API schema being served is cached or not. func (c *FakeDiscovery) HasOpenAPISchemaChanged() bool { return true } diff --git a/staging/src/k8s.io/client-go/rest/request.go b/staging/src/k8s.io/client-go/rest/request.go index caaf737ec5d..55a6df55635 100644 --- a/staging/src/k8s.io/client-go/rest/request.go +++ b/staging/src/k8s.io/client-go/rest/request.go @@ -1062,12 +1062,6 @@ func (r *Request) DoRaw(ctx context.Context) ([]byte, error) { // transformResponse converts an API response into a structured API object func (r *Request) transformResponse(resp *http.Response, req *http.Request) Result { - var etag string - etagHeader, ok := resp.Header["Etag"] - if ok && len(etagHeader) == 1 { - etag = etagHeader[0] - } - var body []byte if resp.Body != nil { data, err := ioutil.ReadAll(resp.Body) @@ -1146,6 +1140,14 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu } } + // store the etag header so that we can check whether the document + // has changed or not. + var etag string + etagHeader, ok := resp.Header["Etag"] + if ok && len(etagHeader) == 1 { + etag = etagHeader[0] + } + return Result{ body: body, contentType: contentType,