k8s.io/apiserver@v0.31.1/pkg/endpoints/groupversion.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package endpoints 18 19 import ( 20 "path" 21 "time" 22 23 restful "github.com/emicklei/go-restful/v3" 24 25 apidiscoveryv2 "k8s.io/api/apidiscovery/v2" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/runtime" 28 "k8s.io/apimachinery/pkg/runtime/schema" 29 utilerrors "k8s.io/apimachinery/pkg/util/errors" 30 "k8s.io/apimachinery/pkg/util/managedfields" 31 "k8s.io/apimachinery/pkg/util/sets" 32 "k8s.io/apiserver/pkg/admission" 33 "k8s.io/apiserver/pkg/authorization/authorizer" 34 "k8s.io/apiserver/pkg/endpoints/discovery" 35 "k8s.io/apiserver/pkg/registry/rest" 36 "k8s.io/apiserver/pkg/storageversion" 37 ) 38 39 // ConvertabilityChecker indicates what versions a GroupKind is available in. 40 type ConvertabilityChecker interface { 41 // VersionsForGroupKind indicates what versions are available to convert a group kind. This determines 42 // what our decoding abilities are. 43 VersionsForGroupKind(gk schema.GroupKind) []schema.GroupVersion 44 } 45 46 // APIGroupVersion is a helper for exposing rest.Storage objects as http.Handlers via go-restful 47 // It handles URLs of the form: 48 // /${storage_key}[/${object_name}] 49 // Where 'storage_key' points to a rest.Storage object stored in storage. 50 // This object should contain all parameterization necessary for running a particular API version 51 type APIGroupVersion struct { 52 Storage map[string]rest.Storage 53 54 Root string 55 56 // GroupVersion is the external group version 57 GroupVersion schema.GroupVersion 58 59 // AllServedVersionsByResource is indexed by resource and maps to a list of versions that resource exists in. 60 // This was created so that StorageVersion for APIs can include a list of all version that are served for each 61 // GroupResource tuple. 62 AllServedVersionsByResource map[string][]string 63 64 // OptionsExternalVersion controls the Kubernetes APIVersion used for common objects in the apiserver 65 // schema like api.Status, api.DeleteOptions, and metav1.ListOptions. Other implementors may 66 // define a version "v1beta1" but want to use the Kubernetes "v1" internal objects. If 67 // empty, defaults to GroupVersion. 68 OptionsExternalVersion *schema.GroupVersion 69 // MetaGroupVersion defaults to "meta.k8s.io/v1" and is the scheme group version used to decode 70 // common API implementations like ListOptions. Future changes will allow this to vary by group 71 // version (for when the inevitable meta/v2 group emerges). 72 MetaGroupVersion *schema.GroupVersion 73 74 // RootScopedKinds are the root scoped kinds for the primary GroupVersion 75 RootScopedKinds sets.String 76 77 // Serializer is used to determine how to convert responses from API methods into bytes to send over 78 // the wire. 79 Serializer runtime.NegotiatedSerializer 80 ParameterCodec runtime.ParameterCodec 81 82 Typer runtime.ObjectTyper 83 Creater runtime.ObjectCreater 84 Convertor runtime.ObjectConvertor 85 ConvertabilityChecker ConvertabilityChecker 86 Defaulter runtime.ObjectDefaulter 87 Namer runtime.Namer 88 UnsafeConvertor runtime.ObjectConvertor 89 TypeConverter managedfields.TypeConverter 90 91 EquivalentResourceRegistry runtime.EquivalentResourceRegistry 92 93 // Authorizer determines whether a user is allowed to make a certain request. The Handler does a preliminary 94 // authorization check using the request URI but it may be necessary to make additional checks, such as in 95 // the create-on-update case 96 Authorizer authorizer.Authorizer 97 98 Admit admission.Interface 99 100 MinRequestTimeout time.Duration 101 102 // The limit on the request body size that would be accepted and decoded in a write request. 103 // 0 means no limit. 104 MaxRequestBodyBytes int64 105 } 106 107 // InstallREST registers the REST handlers (storage, watch, proxy and redirect) into a restful Container. 108 // It is expected that the provided path root prefix will serve all operations. Root MUST NOT end 109 // in a slash. 110 func (g *APIGroupVersion) InstallREST(container *restful.Container) ([]apidiscoveryv2.APIResourceDiscovery, []*storageversion.ResourceInfo, error) { 111 prefix := path.Join(g.Root, g.GroupVersion.Group, g.GroupVersion.Version) 112 installer := &APIInstaller{ 113 group: g, 114 prefix: prefix, 115 minRequestTimeout: g.MinRequestTimeout, 116 } 117 118 apiResources, resourceInfos, ws, registrationErrors := installer.Install() 119 versionDiscoveryHandler := discovery.NewAPIVersionHandler(g.Serializer, g.GroupVersion, staticLister{apiResources}) 120 versionDiscoveryHandler.AddToWebService(ws) 121 container.Add(ws) 122 aggregatedDiscoveryResources, err := ConvertGroupVersionIntoToDiscovery(apiResources) 123 if err != nil { 124 registrationErrors = append(registrationErrors, err) 125 } 126 return aggregatedDiscoveryResources, removeNonPersistedResources(resourceInfos), utilerrors.NewAggregate(registrationErrors) 127 } 128 129 func removeNonPersistedResources(infos []*storageversion.ResourceInfo) []*storageversion.ResourceInfo { 130 var filtered []*storageversion.ResourceInfo 131 for _, info := range infos { 132 // if EncodingVersion is empty, then the apiserver does not 133 // need to register this resource via the storage version API, 134 // thus we can remove it. 135 if info != nil && len(info.EncodingVersion) > 0 { 136 filtered = append(filtered, info) 137 } 138 } 139 return filtered 140 } 141 142 // staticLister implements the APIResourceLister interface 143 type staticLister struct { 144 list []metav1.APIResource 145 } 146 147 func (s staticLister) ListAPIResources() []metav1.APIResource { 148 return s.list 149 } 150 151 var _ discovery.APIResourceLister = &staticLister{}