...

Source file src/k8s.io/kubernetes/plugin/pkg/admission/storage/storageclass/setdefault/admission.go

Documentation: k8s.io/kubernetes/plugin/pkg/admission/storage/storageclass/setdefault

     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 setdefault
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"io"
    23  	"k8s.io/kubernetes/pkg/volume/util"
    24  
    25  	"k8s.io/klog/v2"
    26  
    27  	"k8s.io/apiserver/pkg/admission"
    28  	genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer"
    29  	"k8s.io/client-go/informers"
    30  	storagev1listers "k8s.io/client-go/listers/storage/v1"
    31  	api "k8s.io/kubernetes/pkg/apis/core"
    32  	"k8s.io/kubernetes/pkg/apis/core/helper"
    33  )
    34  
    35  const (
    36  	// PluginName is the name of this admission controller plugin
    37  	PluginName = "DefaultStorageClass"
    38  )
    39  
    40  // Register registers a plugin
    41  func Register(plugins *admission.Plugins) {
    42  	plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
    43  		plugin := newPlugin()
    44  		return plugin, nil
    45  	})
    46  }
    47  
    48  // claimDefaulterPlugin holds state for and implements the admission plugin.
    49  type claimDefaulterPlugin struct {
    50  	*admission.Handler
    51  
    52  	lister storagev1listers.StorageClassLister
    53  }
    54  
    55  var _ admission.Interface = &claimDefaulterPlugin{}
    56  var _ admission.MutationInterface = &claimDefaulterPlugin{}
    57  var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&claimDefaulterPlugin{})
    58  
    59  // newPlugin creates a new admission plugin.
    60  func newPlugin() *claimDefaulterPlugin {
    61  	return &claimDefaulterPlugin{
    62  		Handler: admission.NewHandler(admission.Create),
    63  	}
    64  }
    65  
    66  func (a *claimDefaulterPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
    67  	informer := f.Storage().V1().StorageClasses()
    68  	a.lister = informer.Lister()
    69  	a.SetReadyFunc(informer.Informer().HasSynced)
    70  }
    71  
    72  // ValidateInitialization ensures lister is set.
    73  func (a *claimDefaulterPlugin) ValidateInitialization() error {
    74  	if a.lister == nil {
    75  		return fmt.Errorf("missing lister")
    76  	}
    77  	return nil
    78  }
    79  
    80  // Admit sets the default value of a PersistentVolumeClaim's storage class, in case the user did
    81  // not provide a value.
    82  //
    83  // 1.  Find available StorageClasses.
    84  // 2.  Figure which is the default
    85  // 3.  Write to the PVClaim
    86  func (a *claimDefaulterPlugin) Admit(ctx context.Context, attr admission.Attributes, o admission.ObjectInterfaces) error {
    87  	if attr.GetResource().GroupResource() != api.Resource("persistentvolumeclaims") {
    88  		return nil
    89  	}
    90  
    91  	if len(attr.GetSubresource()) != 0 {
    92  		return nil
    93  	}
    94  
    95  	pvc, ok := attr.GetObject().(*api.PersistentVolumeClaim)
    96  	// if we can't convert then we don't handle this object so just return
    97  	if !ok {
    98  		return nil
    99  	}
   100  
   101  	if helper.PersistentVolumeClaimHasClass(pvc) {
   102  		// The user asked for a class.
   103  		return nil
   104  	}
   105  
   106  	klog.V(4).Infof("no storage class for claim %s (generate: %s)", pvc.Name, pvc.GenerateName)
   107  
   108  	def, err := util.GetDefaultClass(a.lister)
   109  	if err != nil {
   110  		return admission.NewForbidden(attr, err)
   111  	}
   112  	if def == nil {
   113  		// No default class selected, do nothing about the PVC.
   114  		return nil
   115  	}
   116  
   117  	klog.V(4).Infof("defaulting storage class for claim %s (generate: %s) to %s", pvc.Name, pvc.GenerateName, def.Name)
   118  	pvc.Spec.StorageClassName = &def.Name
   119  	return nil
   120  }
   121  

View as plain text