k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/registry/core/rest/storage_core_generic.go (about) 1 /* 2 Copyright 2023 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 rest 18 19 import ( 20 "context" 21 "time" 22 23 corev1 "k8s.io/api/core/v1" 24 "k8s.io/apimachinery/pkg/api/errors" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/runtime" 27 "k8s.io/apimachinery/pkg/runtime/schema" 28 "k8s.io/apiserver/pkg/authentication/authenticator" 29 "k8s.io/apiserver/pkg/registry/generic" 30 "k8s.io/apiserver/pkg/registry/rest" 31 genericapiserver "k8s.io/apiserver/pkg/server" 32 serverstorage "k8s.io/apiserver/pkg/server/storage" 33 "k8s.io/client-go/informers" 34 restclient "k8s.io/client-go/rest" 35 36 "k8s.io/kubernetes/pkg/api/legacyscheme" 37 api "k8s.io/kubernetes/pkg/apis/core" 38 configmapstore "k8s.io/kubernetes/pkg/registry/core/configmap/storage" 39 eventstore "k8s.io/kubernetes/pkg/registry/core/event/storage" 40 namespacestore "k8s.io/kubernetes/pkg/registry/core/namespace/storage" 41 resourcequotastore "k8s.io/kubernetes/pkg/registry/core/resourcequota/storage" 42 secretstore "k8s.io/kubernetes/pkg/registry/core/secret/storage" 43 serviceaccountstore "k8s.io/kubernetes/pkg/registry/core/serviceaccount/storage" 44 "k8s.io/kubernetes/pkg/serviceaccount" 45 ) 46 47 // GenericConfig provides information needed to build RESTStorage 48 // for generic resources in core. It implements the "normal" RESTStorageProvider interface. 49 type GenericConfig struct { 50 StorageFactory serverstorage.StorageFactory 51 EventTTL time.Duration 52 53 ServiceAccountIssuer serviceaccount.TokenGenerator 54 ServiceAccountMaxExpiration time.Duration 55 ExtendExpiration bool 56 57 APIAudiences authenticator.Audiences 58 59 LoopbackClientConfig *restclient.Config 60 Informers informers.SharedInformerFactory 61 } 62 63 func (c *GenericConfig) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) { 64 apiGroupInfo := genericapiserver.APIGroupInfo{ 65 PrioritizedVersions: legacyscheme.Scheme.PrioritizedVersionsForGroup(""), 66 VersionedResourcesStorageMap: map[string]map[string]rest.Storage{}, 67 Scheme: legacyscheme.Scheme, 68 ParameterCodec: legacyscheme.ParameterCodec, 69 NegotiatedSerializer: legacyscheme.Codecs, 70 } 71 72 eventStorage, err := eventstore.NewREST(restOptionsGetter, uint64(c.EventTTL.Seconds())) 73 if err != nil { 74 return genericapiserver.APIGroupInfo{}, err 75 } 76 77 resourceQuotaStorage, resourceQuotaStatusStorage, err := resourcequotastore.NewREST(restOptionsGetter) 78 if err != nil { 79 return genericapiserver.APIGroupInfo{}, err 80 } 81 secretStorage, err := secretstore.NewREST(restOptionsGetter) 82 if err != nil { 83 return genericapiserver.APIGroupInfo{}, err 84 } 85 86 configMapStorage, err := configmapstore.NewREST(restOptionsGetter) 87 if err != nil { 88 return genericapiserver.APIGroupInfo{}, err 89 } 90 91 namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage, err := namespacestore.NewREST(restOptionsGetter) 92 if err != nil { 93 return genericapiserver.APIGroupInfo{}, err 94 } 95 96 var serviceAccountStorage *serviceaccountstore.REST 97 if c.ServiceAccountIssuer != nil { 98 serviceAccountStorage, err = serviceaccountstore.NewREST(restOptionsGetter, c.ServiceAccountIssuer, c.APIAudiences, c.ServiceAccountMaxExpiration, newNotFoundGetter(schema.GroupResource{Resource: "pods"}), secretStorage.Store, newNotFoundGetter(schema.GroupResource{Resource: "nodes"}), c.ExtendExpiration) 99 } else { 100 serviceAccountStorage, err = serviceaccountstore.NewREST(restOptionsGetter, nil, nil, 0, newNotFoundGetter(schema.GroupResource{Resource: "pods"}), newNotFoundGetter(schema.GroupResource{Resource: "secrets"}), newNotFoundGetter(schema.GroupResource{Resource: "nodes"}), false) 101 } 102 if err != nil { 103 return genericapiserver.APIGroupInfo{}, err 104 } 105 106 storage := map[string]rest.Storage{} 107 if resource := "events"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) { 108 storage[resource] = eventStorage 109 } 110 111 if resource := "resourcequotas"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) { 112 storage[resource] = resourceQuotaStorage 113 storage[resource+"/status"] = resourceQuotaStatusStorage 114 } 115 116 if resource := "namespaces"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) { 117 storage[resource] = namespaceStorage 118 storage[resource+"/status"] = namespaceStatusStorage 119 storage[resource+"/finalize"] = namespaceFinalizeStorage 120 } 121 122 if resource := "secrets"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) { 123 storage[resource] = secretStorage 124 } 125 126 if resource := "serviceaccounts"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) { 127 storage[resource] = serviceAccountStorage 128 if serviceAccountStorage.Token != nil { 129 storage[resource+"/token"] = serviceAccountStorage.Token 130 } 131 } 132 133 if resource := "configmaps"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) { 134 storage[resource] = configMapStorage 135 } 136 137 if len(storage) > 0 { 138 apiGroupInfo.VersionedResourcesStorageMap["v1"] = storage 139 } 140 141 return apiGroupInfo, nil 142 } 143 144 func (c *GenericConfig) GroupName() string { 145 return api.GroupName 146 } 147 148 func newNotFoundGetter(gr schema.GroupResource) rest.Getter { 149 return notFoundGetter{gr: gr} 150 } 151 152 type notFoundGetter struct { 153 gr schema.GroupResource 154 } 155 156 func (g notFoundGetter) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { 157 return nil, errors.NewNotFound(g.gr, name) 158 }