provide directly decodable versions for storageversion API

Kubernetes-commit: fa03dee68cea605b285b00ae5b6ce22659d95026
This commit is contained in:
David Eads 2021-03-08 09:33:46 -05:00 committed by Kubernetes Publisher
parent 605b55af85
commit 3f9e652c39
4 changed files with 50 additions and 18 deletions

View File

@ -36,6 +36,13 @@ import (
openapiproto "k8s.io/kube-openapi/pkg/util/proto"
)
// ConvertabilityChecker indicates what versions a GroupKind is available in.
type ConvertabilityChecker interface {
// VersionsForGroupKind indicates what versions are available to convert a group kind. This determines
// what our decoding abilities are.
VersionsForGroupKind(gk schema.GroupKind) []schema.GroupVersion
}
// APIGroupVersion is a helper for exposing rest.Storage objects as http.Handlers via go-restful
// It handles URLs of the form:
// /${storage_key}[/${object_name}]
@ -70,6 +77,7 @@ type APIGroupVersion struct {
Typer runtime.ObjectTyper
Creater runtime.ObjectCreater
Convertor runtime.ObjectConvertor
ConvertabilityChecker ConvertabilityChecker
Defaulter runtime.ObjectDefaulter
Linker runtime.SelfLinker
UnsafeConvertor runtime.ObjectConvertor

View File

@ -513,6 +513,10 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if err != nil {
return nil, nil, err
}
decodableVersions := []schema.GroupVersion{}
if a.group.ConvertabilityChecker != nil {
decodableVersions = a.group.ConvertabilityChecker.VersionsForGroupKind(fqKindToRegister.GroupKind())
}
resourceInfo = &storageversion.ResourceInfo{
GroupResource: schema.GroupResource{
Group: a.group.GroupVersion.Group,
@ -523,6 +527,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
// DecodableVersions immediately because API installation must
// be completed first for us to know equivalent APIs
EquivalentResourceMapper: a.group.EquivalentResourceRegistry,
DirectlyDecodableVersions: decodableVersions,
}
}

View File

@ -553,6 +553,7 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
Serializer: apiGroupInfo.NegotiatedSerializer,
Creater: apiGroupInfo.Scheme,
Convertor: apiGroupInfo.Scheme,
ConvertabilityChecker: apiGroupInfo.Scheme,
UnsafeConvertor: runtime.UnsafeObjectConvertor(apiGroupInfo.Scheme),
Defaulter: apiGroupInfo.Scheme,
Typer: apiGroupInfo.Scheme,

View File

@ -40,6 +40,10 @@ type ResourceInfo struct {
// Used to calculate decodable versions. Can only be used after all
// equivalent versions are registered by InstallREST.
EquivalentResourceMapper runtime.EquivalentResourceRegistry
// DirectlyDecodableVersions is a list of versions that the converter for REST storage knows how to convert. This
// contains items like apiextensions.k8s.io/v1beta1 even if we don't serve that version.
DirectlyDecodableVersions []schema.GroupVersion
}
// Manager records the resources whose StorageVersions need updates, and provides a method to update those StorageVersions.
@ -133,13 +137,13 @@ func (s *defaultManager) UpdateStorageVersions(kubeAPIServerClientConfig *rest.C
// StorageVersion objects have CommonEncodingVersion (each with one server registered).
sortResourceInfosByGroupResource(resources)
for _, r := range dedupResourceInfos(resources) {
dv := decodableVersions(r.EquivalentResourceMapper, r.GroupResource)
decodableVersions := decodableVersions(r.DirectlyDecodableVersions, r.EquivalentResourceMapper, r.GroupResource)
gr := r.GroupResource
// Group must be a valid subdomain in DNS (RFC 1123)
if len(gr.Group) == 0 {
gr.Group = "core"
}
if err := updateStorageVersionFor(sc, serverID, gr, r.EncodingVersion, dv); err != nil {
if err := updateStorageVersionFor(sc, serverID, gr, r.EncodingVersion, decodableVersions); err != nil {
utilruntime.HandleError(fmt.Errorf("failed to update storage version for %v: %v", r.GroupResource, err))
s.recordStatusFailure(&r, err)
hasFailure = true
@ -267,10 +271,23 @@ func (s *defaultManager) Completed() bool {
return s.completed.Load().(bool)
}
func decodableVersions(e runtime.EquivalentResourceRegistry, gr schema.GroupResource) []string {
func decodableVersions(directlyDecodableVersions []schema.GroupVersion, e runtime.EquivalentResourceRegistry, gr schema.GroupResource) []string {
var versions []string
for _, decodableVersions := range directlyDecodableVersions {
versions = append(versions, decodableVersions.String())
}
decodingGVRs := e.EquivalentResourcesFor(gr.WithVersion(""), "")
for _, v := range decodingGVRs {
found := false
for _, existingVersion := range versions {
if existingVersion == v.GroupVersion().String() {
found = true
}
}
if found {
continue
}
versions = append(versions, v.GroupVersion().String())
}
return versions