...

Source file src/k8s.io/kubernetes/pkg/registry/core/persistentvolumeclaim/strategy.go

Documentation: k8s.io/kubernetes/pkg/registry/core/persistentvolumeclaim

     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 persistentvolumeclaim
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  
    23  	"k8s.io/apimachinery/pkg/fields"
    24  	"k8s.io/apimachinery/pkg/labels"
    25  	"k8s.io/apimachinery/pkg/runtime"
    26  	"k8s.io/apimachinery/pkg/util/validation/field"
    27  	"k8s.io/apiserver/pkg/registry/generic"
    28  	"k8s.io/apiserver/pkg/storage"
    29  	"k8s.io/apiserver/pkg/storage/names"
    30  	"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
    31  
    32  	"k8s.io/kubernetes/pkg/api/legacyscheme"
    33  	pvcutil "k8s.io/kubernetes/pkg/api/persistentvolumeclaim"
    34  	api "k8s.io/kubernetes/pkg/apis/core"
    35  	"k8s.io/kubernetes/pkg/apis/core/validation"
    36  )
    37  
    38  // persistentvolumeclaimStrategy implements behavior for PersistentVolumeClaim objects
    39  type persistentvolumeclaimStrategy struct {
    40  	runtime.ObjectTyper
    41  	names.NameGenerator
    42  }
    43  
    44  // Strategy is the default logic that applies when creating and updating PersistentVolumeClaim
    45  // objects via the REST API.
    46  var Strategy = persistentvolumeclaimStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
    47  
    48  func (persistentvolumeclaimStrategy) NamespaceScoped() bool {
    49  	return true
    50  }
    51  
    52  // GetResetFields returns the set of fields that get reset by the strategy
    53  // and should not be modified by the user.
    54  func (persistentvolumeclaimStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
    55  	fields := map[fieldpath.APIVersion]*fieldpath.Set{
    56  		"v1": fieldpath.NewSet(
    57  			fieldpath.MakePathOrDie("status"),
    58  		),
    59  	}
    60  
    61  	return fields
    62  }
    63  
    64  // PrepareForCreate clears the Status field which is not allowed to be set by end users on creation.
    65  func (persistentvolumeclaimStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
    66  	pvc := obj.(*api.PersistentVolumeClaim)
    67  	pvc.Status = api.PersistentVolumeClaimStatus{}
    68  	pvcutil.DropDisabledFields(&pvc.Spec, nil)
    69  
    70  	// For data sources, we need to do 2 things to implement KEP 1495
    71  
    72  	// First drop invalid values from spec.dataSource (anything other than PVC or
    73  	// VolumeSnapshot) if certain conditions are met.
    74  	pvcutil.EnforceDataSourceBackwardsCompatibility(&pvc.Spec, nil)
    75  
    76  	// Second copy dataSource -> dataSourceRef or dataSourceRef -> dataSource if one of them
    77  	// is nil and the other is non-nil
    78  	pvcutil.NormalizeDataSources(&pvc.Spec)
    79  }
    80  
    81  func (persistentvolumeclaimStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
    82  	pvc := obj.(*api.PersistentVolumeClaim)
    83  	opts := validation.ValidationOptionsForPersistentVolumeClaim(pvc, nil)
    84  	return validation.ValidatePersistentVolumeClaim(pvc, opts)
    85  }
    86  
    87  // WarningsOnCreate returns warnings for the creation of the given object.
    88  func (persistentvolumeclaimStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string {
    89  	return pvcutil.GetWarningsForPersistentVolumeClaim(obj.(*api.PersistentVolumeClaim))
    90  }
    91  
    92  // Canonicalize normalizes the object after validation.
    93  func (persistentvolumeclaimStrategy) Canonicalize(obj runtime.Object) {
    94  }
    95  
    96  func (persistentvolumeclaimStrategy) AllowCreateOnUpdate() bool {
    97  	return false
    98  }
    99  
   100  // PrepareForUpdate sets the Status field which is not allowed to be set by end users on update
   101  func (persistentvolumeclaimStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
   102  	newPvc := obj.(*api.PersistentVolumeClaim)
   103  	oldPvc := old.(*api.PersistentVolumeClaim)
   104  	newPvc.Status = oldPvc.Status
   105  
   106  	pvcutil.DropDisabledFields(&newPvc.Spec, &oldPvc.Spec)
   107  
   108  	// We need to use similar logic to PrepareForCreate here both to preserve backwards
   109  	// compatibility with the old behavior (ignoring of garbage dataSources at both create
   110  	// and update time) and also for compatibility with older clients, that might omit
   111  	// the dataSourceRef field which we filled in automatically, so we have to fill it
   112  	// in again here.
   113  	pvcutil.EnforceDataSourceBackwardsCompatibility(&newPvc.Spec, &oldPvc.Spec)
   114  	pvcutil.NormalizeDataSources(&newPvc.Spec)
   115  
   116  	// We also normalize the data source fields of the old PVC, so that objects saved
   117  	// from an earlier version will pass validation.
   118  	pvcutil.NormalizeDataSources(&oldPvc.Spec)
   119  }
   120  
   121  func (persistentvolumeclaimStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
   122  	newPvc := obj.(*api.PersistentVolumeClaim)
   123  	oldPvc := old.(*api.PersistentVolumeClaim)
   124  	opts := validation.ValidationOptionsForPersistentVolumeClaim(newPvc, oldPvc)
   125  	errorList := validation.ValidatePersistentVolumeClaim(newPvc, opts)
   126  	return append(errorList, validation.ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc, opts)...)
   127  }
   128  
   129  // WarningsOnUpdate returns warnings for the given update.
   130  func (persistentvolumeclaimStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string {
   131  	return pvcutil.GetWarningsForPersistentVolumeClaim(obj.(*api.PersistentVolumeClaim))
   132  }
   133  
   134  func (persistentvolumeclaimStrategy) AllowUnconditionalUpdate() bool {
   135  	return true
   136  }
   137  
   138  type persistentvolumeclaimStatusStrategy struct {
   139  	persistentvolumeclaimStrategy
   140  }
   141  
   142  var StatusStrategy = persistentvolumeclaimStatusStrategy{Strategy}
   143  
   144  // GetResetFields returns the set of fields that get reset by the strategy
   145  // and should not be modified by the user.
   146  func (persistentvolumeclaimStatusStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
   147  	fields := map[fieldpath.APIVersion]*fieldpath.Set{
   148  		"v1": fieldpath.NewSet(
   149  			fieldpath.MakePathOrDie("spec"),
   150  		),
   151  	}
   152  
   153  	return fields
   154  }
   155  
   156  // PrepareForUpdate sets the Spec field which is not allowed to be changed when updating a PV's Status
   157  func (persistentvolumeclaimStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
   158  	newPVC := obj.(*api.PersistentVolumeClaim)
   159  	oldPVC := old.(*api.PersistentVolumeClaim)
   160  	newPVC.Spec = oldPVC.Spec
   161  	pvcutil.DropDisabledFieldsFromStatus(newPVC, oldPVC)
   162  }
   163  
   164  func (persistentvolumeclaimStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
   165  	newPvc := obj.(*api.PersistentVolumeClaim)
   166  	oldPvc := old.(*api.PersistentVolumeClaim)
   167  	opts := validation.ValidationOptionsForPersistentVolumeClaim(newPvc, oldPvc)
   168  	return validation.ValidatePersistentVolumeClaimStatusUpdate(newPvc, oldPvc, opts)
   169  }
   170  
   171  // WarningsOnUpdate returns warnings for the given update.
   172  func (persistentvolumeclaimStatusStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string {
   173  	return nil
   174  }
   175  
   176  // GetAttrs returns labels and fields of a given object for filtering purposes.
   177  func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
   178  	persistentvolumeclaimObj, ok := obj.(*api.PersistentVolumeClaim)
   179  	if !ok {
   180  		return nil, nil, fmt.Errorf("not a persistentvolumeclaim")
   181  	}
   182  	return labels.Set(persistentvolumeclaimObj.Labels), PersistentVolumeClaimToSelectableFields(persistentvolumeclaimObj), nil
   183  }
   184  
   185  // MatchPersistentVolumeClaim returns a generic matcher for a given label and field selector.
   186  func MatchPersistentVolumeClaim(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
   187  	return storage.SelectionPredicate{
   188  		Label:    label,
   189  		Field:    field,
   190  		GetAttrs: GetAttrs,
   191  	}
   192  }
   193  
   194  // PersistentVolumeClaimToSelectableFields returns a field set that represents the object
   195  func PersistentVolumeClaimToSelectableFields(persistentvolumeclaim *api.PersistentVolumeClaim) fields.Set {
   196  	objectMetaFieldsSet := generic.ObjectMetaFieldsSet(&persistentvolumeclaim.ObjectMeta, true)
   197  	specificFieldsSet := fields.Set{
   198  		// This is a bug, but we need to support it for backward compatibility.
   199  		"name": persistentvolumeclaim.Name,
   200  	}
   201  	return generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet)
   202  }
   203  

View as plain text