Merge pull request #54683 from liggitt/subresource-gvk
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Fix subresource discovery and versioning Fixes https://github.com/kubernetes/kubernetes/issues/54684 Related to https://github.com/kubernetes/kubernetes/pull/54586 Allows distinct subresource group/version/kind to be used for each version (gives us a path to move to autoscaling/v1 for apps, or policy/v1 for eviction, etc) Added tests to ensure scale subresources have expected discovery info, and that the object returned matches discovery, and that the endpoint accepts the advertised version ```release-note Fixes discovery information for scale subresources in the apps API group ``` Kubernetes-commit: 0c1f25fc1ba118ade226dad74052e4e45a16bcb6
This commit is contained in:
		
						commit
						dc5f59979b
					
				|  | @ -3867,7 +3867,8 @@ func TestUpdateChecksAPIVersion(t *testing.T) { | |||
| } | ||||
| 
 | ||||
| type SimpleXGSubresourceRESTStorage struct { | ||||
| 	item genericapitesting.SimpleXGSubresource | ||||
| 	item    genericapitesting.SimpleXGSubresource | ||||
| 	itemGVK schema.GroupVersionKind | ||||
| } | ||||
| 
 | ||||
| func (storage *SimpleXGSubresourceRESTStorage) New() runtime.Object { | ||||
|  | @ -3878,6 +3879,12 @@ func (storage *SimpleXGSubresourceRESTStorage) Get(ctx request.Context, id strin | |||
| 	return storage.item.DeepCopyObject(), nil | ||||
| } | ||||
| 
 | ||||
| var _ = rest.GroupVersionKindProvider(&SimpleXGSubresourceRESTStorage{}) | ||||
| 
 | ||||
| func (storage *SimpleXGSubresourceRESTStorage) GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind { | ||||
| 	return storage.itemGVK | ||||
| } | ||||
| 
 | ||||
| func TestXGSubresource(t *testing.T) { | ||||
| 	container := restful.NewContainer() | ||||
| 	container.Router(restful.CurlyRouter{}) | ||||
|  | @ -3888,6 +3895,7 @@ func TestXGSubresource(t *testing.T) { | |||
| 		item: genericapitesting.SimpleXGSubresource{ | ||||
| 			SubresourceInfo: "foo", | ||||
| 		}, | ||||
| 		itemGVK: testGroup2Version.WithKind("SimpleXGSubresource"), | ||||
| 	} | ||||
| 	storage := map[string]rest.Storage{ | ||||
| 		"simple":           &SimpleRESTStorage{}, | ||||
|  | @ -3913,10 +3921,6 @@ func TestXGSubresource(t *testing.T) { | |||
| 		GroupVersion:           testGroupVersion, | ||||
| 		OptionsExternalVersion: &testGroupVersion, | ||||
| 		Serializer:             codecs, | ||||
| 
 | ||||
| 		SubresourceGroupVersionKind: map[string]schema.GroupVersionKind{ | ||||
| 			"simple/subsimple": testGroup2Version.WithKind("SimpleXGSubresource"), | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	if err := (&group).InstallREST(container); err != nil { | ||||
|  |  | |||
|  | @ -75,12 +75,6 @@ type APIGroupVersion struct { | |||
| 
 | ||||
| 	MinRequestTimeout time.Duration | ||||
| 
 | ||||
| 	// SubresourceGroupVersionKind contains the GroupVersionKind overrides for each subresource that is
 | ||||
| 	// accessible from this API group version. The GroupVersionKind is that of the external version of
 | ||||
| 	// the subresource. The key of this map should be the path of the subresource. The keys here should
 | ||||
| 	// match the keys in the Storage map above for subresources.
 | ||||
| 	SubresourceGroupVersionKind map[string]schema.GroupVersionKind | ||||
| 
 | ||||
| 	// EnableAPIResponseCompression indicates whether API Responses should support compression
 | ||||
| 	// if the client requests it via Accept-Encoding
 | ||||
| 	EnableAPIResponseCompression bool | ||||
|  |  | |||
|  | @ -144,8 +144,9 @@ func (a *APIInstaller) newWebService() *restful.WebService { | |||
| // object. If the storage object is a subresource and has an override supplied for it, it returns
 | ||||
| // the group version kind supplied in the override.
 | ||||
| func (a *APIInstaller) getResourceKind(path string, storage rest.Storage) (schema.GroupVersionKind, error) { | ||||
| 	if fqKindToRegister, ok := a.group.SubresourceGroupVersionKind[path]; ok { | ||||
| 		return fqKindToRegister, nil | ||||
| 	// Let the storage tell us exactly what GVK it has
 | ||||
| 	if gvkProvider, ok := storage.(rest.GroupVersionKindProvider); ok { | ||||
| 		return gvkProvider.GroupVersionKind(a.group.GroupVersion), nil | ||||
| 	} | ||||
| 
 | ||||
| 	object := storage.New() | ||||
|  | @ -162,12 +163,6 @@ func (a *APIInstaller) getResourceKind(path string, storage rest.Storage) (schem | |||
| 			fqKindToRegister = a.group.GroupVersion.WithKind(fqKind.Kind) | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		// TODO: keep rid of extensions api group dependency here
 | ||||
| 		// This keeps it doing what it was doing before, but it doesn't feel right.
 | ||||
| 		if fqKind.Group == "extensions" && fqKind.Kind == "ThirdPartyResourceData" { | ||||
| 			fqKindToRegister = a.group.GroupVersion.WithKind(fqKind.Kind) | ||||
| 		} | ||||
| 	} | ||||
| 	if fqKindToRegister.Empty() { | ||||
| 		return schema.GroupVersionKind{}, fmt.Errorf("unable to locate fully qualified kind for %v: found %v when registering for %v", reflect.TypeOf(object), fqKinds, a.group.GroupVersion) | ||||
|  | @ -878,7 +873,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag | |||
| 		apiResource.Categories = categoriesProvider.Categories() | ||||
| 	} | ||||
| 	if gvkProvider, ok := storage.(rest.GroupVersionKindProvider); ok { | ||||
| 		gvk := gvkProvider.GroupVersionKind() | ||||
| 		gvk := gvkProvider.GroupVersionKind(a.group.GroupVersion) | ||||
| 		apiResource.Group = gvk.Group | ||||
| 		apiResource.Version = gvk.Version | ||||
| 		apiResource.Kind = gvk.Kind | ||||
|  |  | |||
|  | @ -82,7 +82,7 @@ type CategoriesProvider interface { | |||
| // This trumps KindProvider since it is capable of providing the information required.
 | ||||
| // TODO KindProvider (only used by federation) should be removed and replaced with this, but that presents greater risk late in 1.8.
 | ||||
| type GroupVersionKindProvider interface { | ||||
| 	GroupVersionKind() schema.GroupVersionKind | ||||
| 	GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind | ||||
| } | ||||
| 
 | ||||
| // Lister is an object that can retrieve resources that match the provided field and label criteria.
 | ||||
|  |  | |||
|  | @ -70,12 +70,6 @@ type APIGroupInfo struct { | |||
| 	NegotiatedSerializer runtime.NegotiatedSerializer | ||||
| 	// ParameterCodec performs conversions for query parameters passed to API calls
 | ||||
| 	ParameterCodec runtime.ParameterCodec | ||||
| 
 | ||||
| 	// SubresourceGroupVersionKind contains the GroupVersionKind overrides for each subresource that is
 | ||||
| 	// accessible from this API group version. The GroupVersionKind is that of the external version of
 | ||||
| 	// the subresource. The key of this map should be the path of the subresource. The keys here should
 | ||||
| 	// match the keys in the Storage map above for subresources.
 | ||||
| 	SubresourceGroupVersionKind map[string]schema.GroupVersionKind | ||||
| } | ||||
| 
 | ||||
| // GenericAPIServer contains state for a Kubernetes cluster api server.
 | ||||
|  | @ -435,9 +429,8 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV | |||
| 		UnsafeConvertor: runtime.UnsafeObjectConvertor(apiGroupInfo.Scheme), | ||||
| 		Defaulter:       apiGroupInfo.Scheme, | ||||
| 		Typer:           apiGroupInfo.Scheme, | ||||
| 		SubresourceGroupVersionKind: apiGroupInfo.SubresourceGroupVersionKind, | ||||
| 		Linker: apiGroupInfo.GroupMeta.SelfLinker, | ||||
| 		Mapper: apiGroupInfo.GroupMeta.RESTMapper, | ||||
| 		Linker:          apiGroupInfo.GroupMeta.SelfLinker, | ||||
| 		Mapper:          apiGroupInfo.GroupMeta.RESTMapper, | ||||
| 
 | ||||
| 		Admit:                        s.admissionControl, | ||||
| 		Context:                      s.RequestContextMapper(), | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue