k8s.io/kubernetes@v1.29.3/pkg/kubeapiserver/default_storage_factory_builder.go (about)

     1  /*
     2  Copyright 2016 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 kubeapiserver
    18  
    19  import (
    20  	"strings"
    21  
    22  	"k8s.io/apimachinery/pkg/runtime"
    23  	"k8s.io/apimachinery/pkg/runtime/schema"
    24  	serveroptions "k8s.io/apiserver/pkg/server/options"
    25  	"k8s.io/apiserver/pkg/server/resourceconfig"
    26  	serverstorage "k8s.io/apiserver/pkg/server/storage"
    27  	"k8s.io/apiserver/pkg/storage/storagebackend"
    28  	"k8s.io/kubernetes/pkg/api/legacyscheme"
    29  	"k8s.io/kubernetes/pkg/apis/admissionregistration"
    30  	"k8s.io/kubernetes/pkg/apis/apps"
    31  	"k8s.io/kubernetes/pkg/apis/certificates"
    32  	api "k8s.io/kubernetes/pkg/apis/core"
    33  	"k8s.io/kubernetes/pkg/apis/events"
    34  	"k8s.io/kubernetes/pkg/apis/extensions"
    35  	"k8s.io/kubernetes/pkg/apis/networking"
    36  	"k8s.io/kubernetes/pkg/apis/policy"
    37  	"k8s.io/kubernetes/pkg/apis/storage"
    38  )
    39  
    40  // SpecialDefaultResourcePrefixes are prefixes compiled into Kubernetes.
    41  var SpecialDefaultResourcePrefixes = map[schema.GroupResource]string{
    42  	{Group: "", Resource: "replicationcontrollers"}:     "controllers",
    43  	{Group: "", Resource: "endpoints"}:                  "services/endpoints",
    44  	{Group: "", Resource: "nodes"}:                      "minions",
    45  	{Group: "", Resource: "services"}:                   "services/specs",
    46  	{Group: "extensions", Resource: "ingresses"}:        "ingress",
    47  	{Group: "networking.k8s.io", Resource: "ingresses"}: "ingress",
    48  }
    49  
    50  // DefaultWatchCacheSizes defines default resources for which watchcache
    51  // should be disabled.
    52  func DefaultWatchCacheSizes() map[schema.GroupResource]int {
    53  	return map[schema.GroupResource]int{
    54  		{Resource: "events"}:                         0,
    55  		{Group: "events.k8s.io", Resource: "events"}: 0,
    56  	}
    57  }
    58  
    59  // NewStorageFactoryConfig returns a new StorageFactoryConfig set up with necessary resource overrides.
    60  func NewStorageFactoryConfig() *StorageFactoryConfig {
    61  	resources := []schema.GroupVersionResource{
    62  		// If a resource has to be stored in a version that is not the
    63  		// latest, then it can be listed here. Usually this is the case
    64  		// when a new version for a resource gets introduced and a
    65  		// downgrade to an older apiserver that doesn't know the new
    66  		// version still needs to be supported for one release.
    67  		//
    68  		// Example from Kubernetes 1.24 where csistoragecapacities had just
    69  		// graduated to GA:
    70  		//
    71  		// TODO (https://github.com/kubernetes/kubernetes/issues/108451): remove the override in 1.25.
    72  		// apisstorage.Resource("csistoragecapacities").WithVersion("v1beta1"),
    73  		admissionregistration.Resource("validatingadmissionpolicies").WithVersion("v1beta1"),
    74  		admissionregistration.Resource("validatingadmissionpolicybindings").WithVersion("v1beta1"),
    75  		networking.Resource("ipaddresses").WithVersion("v1alpha1"),
    76  		networking.Resource("servicecidrs").WithVersion("v1alpha1"),
    77  		certificates.Resource("clustertrustbundles").WithVersion("v1alpha1"),
    78  		storage.Resource("volumeattributesclasses").WithVersion("v1alpha1"),
    79  	}
    80  
    81  	return &StorageFactoryConfig{
    82  		Serializer:                legacyscheme.Codecs,
    83  		DefaultResourceEncoding:   serverstorage.NewDefaultResourceEncodingConfig(legacyscheme.Scheme),
    84  		ResourceEncodingOverrides: resources,
    85  	}
    86  }
    87  
    88  // StorageFactoryConfig is a configuration for creating storage factory.
    89  type StorageFactoryConfig struct {
    90  	StorageConfig             storagebackend.Config
    91  	APIResourceConfig         *serverstorage.ResourceConfig
    92  	DefaultResourceEncoding   *serverstorage.DefaultResourceEncodingConfig
    93  	DefaultStorageMediaType   string
    94  	Serializer                runtime.StorageSerializer
    95  	ResourceEncodingOverrides []schema.GroupVersionResource
    96  	EtcdServersOverrides      []string
    97  }
    98  
    99  // Complete completes the StorageFactoryConfig with provided etcdOptions returning completedStorageFactoryConfig.
   100  // This method mutates the receiver (StorageFactoryConfig).  It must never mutate the inputs.
   101  func (c *StorageFactoryConfig) Complete(etcdOptions *serveroptions.EtcdOptions) *completedStorageFactoryConfig {
   102  	c.StorageConfig = etcdOptions.StorageConfig
   103  	c.DefaultStorageMediaType = etcdOptions.DefaultStorageMediaType
   104  	c.EtcdServersOverrides = etcdOptions.EtcdServersOverrides
   105  	return &completedStorageFactoryConfig{c}
   106  }
   107  
   108  // completedStorageFactoryConfig is a wrapper around StorageFactoryConfig completed with etcd options.
   109  //
   110  // Note: this struct is intentionally unexported so that it can only be constructed via a StorageFactoryConfig.Complete
   111  // call. The implied consequence is that this does not comply with golint.
   112  type completedStorageFactoryConfig struct {
   113  	*StorageFactoryConfig
   114  }
   115  
   116  // New returns a new storage factory created from the completed storage factory configuration.
   117  func (c *completedStorageFactoryConfig) New() (*serverstorage.DefaultStorageFactory, error) {
   118  	resourceEncodingConfig := resourceconfig.MergeResourceEncodingConfigs(c.DefaultResourceEncoding, c.ResourceEncodingOverrides)
   119  	storageFactory := serverstorage.NewDefaultStorageFactory(
   120  		c.StorageConfig,
   121  		c.DefaultStorageMediaType,
   122  		c.Serializer,
   123  		resourceEncodingConfig,
   124  		c.APIResourceConfig,
   125  		SpecialDefaultResourcePrefixes)
   126  
   127  	storageFactory.AddCohabitatingResources(networking.Resource("networkpolicies"), extensions.Resource("networkpolicies"))
   128  	storageFactory.AddCohabitatingResources(apps.Resource("deployments"), extensions.Resource("deployments"))
   129  	storageFactory.AddCohabitatingResources(apps.Resource("daemonsets"), extensions.Resource("daemonsets"))
   130  	storageFactory.AddCohabitatingResources(apps.Resource("replicasets"), extensions.Resource("replicasets"))
   131  	storageFactory.AddCohabitatingResources(api.Resource("events"), events.Resource("events"))
   132  	storageFactory.AddCohabitatingResources(api.Resource("replicationcontrollers"), extensions.Resource("replicationcontrollers")) // to make scale subresources equivalent
   133  	storageFactory.AddCohabitatingResources(policy.Resource("podsecuritypolicies"), extensions.Resource("podsecuritypolicies"))
   134  	storageFactory.AddCohabitatingResources(networking.Resource("ingresses"), extensions.Resource("ingresses"))
   135  
   136  	for _, override := range c.EtcdServersOverrides {
   137  		tokens := strings.Split(override, "#")
   138  		apiresource := strings.Split(tokens[0], "/")
   139  
   140  		group := apiresource[0]
   141  		resource := apiresource[1]
   142  		groupResource := schema.GroupResource{Group: group, Resource: resource}
   143  
   144  		servers := strings.Split(tokens[1], ";")
   145  		storageFactory.SetEtcdLocation(groupResource, servers)
   146  	}
   147  	return storageFactory, nil
   148  }