mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 02:08:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			145 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2023 The Kubernetes Authors.
 | |
| 
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
| 
 | |
|     http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| package apiserver
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 
 | |
| 	"k8s.io/apiserver/pkg/registry/generic"
 | |
| 	genericapiserver "k8s.io/apiserver/pkg/server"
 | |
| 	serverstorage "k8s.io/apiserver/pkg/server/storage"
 | |
| 	"k8s.io/client-go/discovery"
 | |
| 	"k8s.io/klog/v2"
 | |
| 	svmrest "k8s.io/kubernetes/pkg/registry/storagemigration/rest"
 | |
| 
 | |
| 	admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest"
 | |
| 	apiserverinternalrest "k8s.io/kubernetes/pkg/registry/apiserverinternal/rest"
 | |
| 	authenticationrest "k8s.io/kubernetes/pkg/registry/authentication/rest"
 | |
| 	authorizationrest "k8s.io/kubernetes/pkg/registry/authorization/rest"
 | |
| 	certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest"
 | |
| 	coordinationrest "k8s.io/kubernetes/pkg/registry/coordination/rest"
 | |
| 	corerest "k8s.io/kubernetes/pkg/registry/core/rest"
 | |
| 	eventsrest "k8s.io/kubernetes/pkg/registry/events/rest"
 | |
| 	flowcontrolrest "k8s.io/kubernetes/pkg/registry/flowcontrol/rest"
 | |
| 	rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
 | |
| )
 | |
| 
 | |
| // RESTStorageProvider is a factory type for REST storage.
 | |
| type RESTStorageProvider interface {
 | |
| 	GroupName() string
 | |
| 	NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error)
 | |
| }
 | |
| 
 | |
| // NewCoreGenericConfig returns a new core rest generic config.
 | |
| func (c *CompletedConfig) NewCoreGenericConfig() *corerest.GenericConfig {
 | |
| 	return &corerest.GenericConfig{
 | |
| 		StorageFactory:              c.Extra.StorageFactory,
 | |
| 		EventTTL:                    c.Extra.EventTTL,
 | |
| 		LoopbackClientConfig:        c.Generic.LoopbackClientConfig,
 | |
| 		ServiceAccountIssuer:        c.Extra.ServiceAccountIssuer,
 | |
| 		ExtendExpiration:            c.Extra.ExtendExpiration,
 | |
| 		ServiceAccountMaxExpiration: c.Extra.ServiceAccountMaxExpiration,
 | |
| 		MaxExtendedExpiration:       c.Extra.ServiceAccountExtendedMaxExpiration,
 | |
| 		APIAudiences:                c.Generic.Authentication.APIAudiences,
 | |
| 		Informers:                   c.Extra.VersionedInformers,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // GenericStorageProviders returns a set of APIs for a generic control plane.
 | |
| // They ought to be a subset of those served by kube-apiserver.
 | |
| func (c *CompletedConfig) GenericStorageProviders(discovery discovery.DiscoveryInterface) ([]RESTStorageProvider, error) {
 | |
| 	// The order here is preserved in discovery.
 | |
| 	// If resources with identical names exist in more than one of these groups (e.g. "deployments.apps"" and "deployments.extensions"),
 | |
| 	// the order of this list determines which group an unqualified resource name (e.g. "deployments") should prefer.
 | |
| 	// This priority order is used for local discovery, but it ends up aggregated in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
 | |
| 	// with specific priorities.
 | |
| 	// TODO: describe the priority all the way down in the RESTStorageProviders and plumb it back through the various discovery
 | |
| 	// handlers that we have.
 | |
| 	return []RESTStorageProvider{
 | |
| 		c.NewCoreGenericConfig(),
 | |
| 		apiserverinternalrest.StorageProvider{},
 | |
| 		authenticationrest.RESTStorageProvider{Authenticator: c.Generic.Authentication.Authenticator, APIAudiences: c.Generic.Authentication.APIAudiences},
 | |
| 		authorizationrest.RESTStorageProvider{Authorizer: c.Generic.Authorization.Authorizer, RuleResolver: c.Generic.RuleResolver},
 | |
| 		certificatesrest.RESTStorageProvider{},
 | |
| 		coordinationrest.RESTStorageProvider{},
 | |
| 		rbacrest.RESTStorageProvider{Authorizer: c.Generic.Authorization.Authorizer},
 | |
| 		svmrest.RESTStorageProvider{},
 | |
| 		flowcontrolrest.RESTStorageProvider{InformerFactory: c.Generic.SharedInformerFactory},
 | |
| 		admissionregistrationrest.RESTStorageProvider{Authorizer: c.Generic.Authorization.Authorizer, DiscoveryClient: discovery},
 | |
| 		eventsrest.RESTStorageProvider{TTL: c.EventTTL},
 | |
| 	}, nil
 | |
| }
 | |
| 
 | |
| // InstallAPIs will install the APIs for the restStorageProviders if they are enabled.
 | |
| func (s *Server) InstallAPIs(restStorageProviders ...RESTStorageProvider) error {
 | |
| 	nonLegacy := []*genericapiserver.APIGroupInfo{}
 | |
| 
 | |
| 	// used later in the loop to filter the served resource by those that have expired.
 | |
| 	resourceExpirationEvaluator, err := genericapiserver.NewResourceExpirationEvaluator(s.GenericAPIServer.EffectiveVersion.EmulationVersion())
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	for _, restStorageBuilder := range restStorageProviders {
 | |
| 		groupName := restStorageBuilder.GroupName()
 | |
| 		apiGroupInfo, err := restStorageBuilder.NewRESTStorage(s.APIResourceConfigSource, s.RESTOptionsGetter)
 | |
| 		if err != nil {
 | |
| 			return fmt.Errorf("problem initializing API group %q: %w", groupName, err)
 | |
| 		}
 | |
| 		if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
 | |
| 			// If we have no storage for any resource configured, this API group is effectively disabled.
 | |
| 			// This can happen when an entire API group, version, or development-stage (alpha, beta, GA) is disabled.
 | |
| 			klog.Infof("API group %q is not enabled, skipping.", groupName)
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		// Remove resources that serving kinds that are removed.
 | |
| 		// We do this here so that we don't accidentally serve versions without resources or openapi information that for kinds we don't serve.
 | |
| 		// This is a spot above the construction of individual storage handlers so that no sig accidentally forgets to check.
 | |
| 		resourceExpirationEvaluator.RemoveDeletedKinds(groupName, apiGroupInfo.Scheme, apiGroupInfo.VersionedResourcesStorageMap)
 | |
| 		if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
 | |
| 			klog.V(1).Infof("Removing API group %v because it is time to stop serving it because it has no versions per APILifecycle.", groupName)
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		klog.V(1).Infof("Enabling API group %q.", groupName)
 | |
| 
 | |
| 		if postHookProvider, ok := restStorageBuilder.(genericapiserver.PostStartHookProvider); ok {
 | |
| 			name, hook, err := postHookProvider.PostStartHook()
 | |
| 			if err != nil {
 | |
| 				return fmt.Errorf("error building PostStartHook: %w", err)
 | |
| 			}
 | |
| 			s.GenericAPIServer.AddPostStartHookOrDie(name, hook)
 | |
| 		}
 | |
| 
 | |
| 		if len(groupName) == 0 {
 | |
| 			// the legacy group for core APIs is special that it is installed into /api via this special install method.
 | |
| 			if err := s.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.DefaultLegacyAPIPrefix, &apiGroupInfo); err != nil {
 | |
| 				return fmt.Errorf("error in registering legacy API: %w", err)
 | |
| 			}
 | |
| 		} else {
 | |
| 			// everything else goes to /apis
 | |
| 			nonLegacy = append(nonLegacy, &apiGroupInfo)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if err := s.GenericAPIServer.InstallAPIGroups(nonLegacy...); err != nil {
 | |
| 		return fmt.Errorf("error in registering group versions: %w", err)
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | 
