...

Source file src/k8s.io/kubernetes/pkg/registry/flowcontrol/prioritylevelconfiguration/strategy.go

Documentation: k8s.io/kubernetes/pkg/registry/flowcontrol/prioritylevelconfiguration

     1  /*
     2  Copyright 2019 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 prioritylevelconfiguration
    18  
    19  import (
    20  	"context"
    21  
    22  	apiequality "k8s.io/apimachinery/pkg/api/equality"
    23  	"k8s.io/apimachinery/pkg/runtime"
    24  	"k8s.io/apimachinery/pkg/runtime/schema"
    25  	"k8s.io/apimachinery/pkg/util/validation/field"
    26  	genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
    27  	"k8s.io/apiserver/pkg/storage/names"
    28  	"k8s.io/kubernetes/pkg/api/legacyscheme"
    29  	"k8s.io/kubernetes/pkg/apis/flowcontrol"
    30  	"k8s.io/kubernetes/pkg/apis/flowcontrol/validation"
    31  	"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
    32  )
    33  
    34  // priorityLevelConfigurationStrategy implements verification logic for priority level configurations.
    35  type priorityLevelConfigurationStrategy struct {
    36  	runtime.ObjectTyper
    37  	names.NameGenerator
    38  }
    39  
    40  // Strategy is the default logic that applies when creating and updating priority level configuration objects.
    41  var Strategy = priorityLevelConfigurationStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
    42  
    43  // NamespaceScoped returns false because all PriorityClasses are global.
    44  func (priorityLevelConfigurationStrategy) NamespaceScoped() bool {
    45  	return false
    46  }
    47  
    48  // GetResetFields returns the set of fields that get reset by the strategy
    49  // and should not be modified by the user.
    50  func (priorityLevelConfigurationStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
    51  	fields := map[fieldpath.APIVersion]*fieldpath.Set{
    52  		"flowcontrol.apiserver.k8s.io/v1beta1": fieldpath.NewSet(
    53  			fieldpath.MakePathOrDie("status"),
    54  		),
    55  		"flowcontrol.apiserver.k8s.io/v1beta2": fieldpath.NewSet(
    56  			fieldpath.MakePathOrDie("status"),
    57  		),
    58  		"flowcontrol.apiserver.k8s.io/v1beta3": fieldpath.NewSet(
    59  			fieldpath.MakePathOrDie("status"),
    60  		),
    61  		"flowcontrol.apiserver.k8s.io/v1": fieldpath.NewSet(
    62  			fieldpath.MakePathOrDie("status"),
    63  		),
    64  	}
    65  
    66  	return fields
    67  }
    68  
    69  // PrepareForCreate clears the status of a priority-level-configuration before creation.
    70  func (priorityLevelConfigurationStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
    71  	pl := obj.(*flowcontrol.PriorityLevelConfiguration)
    72  	pl.Status = flowcontrol.PriorityLevelConfigurationStatus{}
    73  	pl.Generation = 1
    74  }
    75  
    76  // PrepareForUpdate clears fields that are not allowed to be set by end users on update.
    77  func (priorityLevelConfigurationStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
    78  	newPriorityLevelConfiguration := obj.(*flowcontrol.PriorityLevelConfiguration)
    79  	oldPriorityLevelConfiguration := old.(*flowcontrol.PriorityLevelConfiguration)
    80  
    81  	// Spec updates bump the generation so that we can distinguish between status updates.
    82  	if !apiequality.Semantic.DeepEqual(newPriorityLevelConfiguration.Spec, oldPriorityLevelConfiguration.Spec) {
    83  		newPriorityLevelConfiguration.Generation = oldPriorityLevelConfiguration.Generation + 1
    84  	}
    85  	newPriorityLevelConfiguration.Status = oldPriorityLevelConfiguration.Status
    86  }
    87  
    88  // Validate validates a new priority-level.
    89  func (priorityLevelConfigurationStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
    90  	// 1.28 server is not aware of the roundtrip annotation, and will
    91  	// default any 0 value persisted (for the NominalConcurrencyShares
    92  	// field of a priority level configuration object) back to 30 when
    93  	// reading from etcd.
    94  	// That means we should not allow 0 values to be introduced, either
    95  	// via v1 or v1beta3(with the roundtrip annotation) until we know
    96  	// all servers are at 1.29+ and will honor the zero value correctly.
    97  	//
    98  	// TODO(121510): 1.29: don't allow a zero value, either via v1 or
    99  	//  v1beta3 (with the roundtrip annotation) for the
   100  	//  'nominalConcurrencyShares' field of 'limited' for CREATE operation.
   101  	//  1:30: lift this restriction, allow zero value via v1 or v1beta3
   102  	opts := validation.PriorityLevelValidationOptions{
   103  		AllowZeroLimitedNominalConcurrencyShares: true,
   104  	}
   105  	return validation.ValidatePriorityLevelConfiguration(obj.(*flowcontrol.PriorityLevelConfiguration), getRequestGroupVersion(ctx), opts)
   106  }
   107  
   108  // WarningsOnCreate returns warnings for the creation of the given object.
   109  func (priorityLevelConfigurationStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string {
   110  	return nil
   111  }
   112  
   113  // Canonicalize normalizes the object after validation.
   114  func (priorityLevelConfigurationStrategy) Canonicalize(obj runtime.Object) {
   115  }
   116  
   117  func (priorityLevelConfigurationStrategy) AllowUnconditionalUpdate() bool {
   118  	return true
   119  }
   120  
   121  // AllowCreateOnUpdate is false for priority-level-configurations; this means a POST is needed to create one.
   122  func (priorityLevelConfigurationStrategy) AllowCreateOnUpdate() bool {
   123  	return false
   124  }
   125  
   126  // ValidateUpdate is the default update validation for an end user.
   127  func (priorityLevelConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
   128  	newPL := obj.(*flowcontrol.PriorityLevelConfiguration)
   129  
   130  	// 1.28 server is not aware of the roundtrip annotation, and will
   131  	// default any 0 value persisted (for the NominalConcurrencyShares
   132  	// field of a priority level configuration object) back to 30 when
   133  	// reading from etcd.
   134  	// That means we should not allow 0 values to be introduced, either
   135  	// via v1 or v1beta3(with the roundtrip annotation) until we know
   136  	// all servers are at 1.29+ and will honor the zero value correctly.
   137  	//
   138  	// TODO(121510): 1.29: only allow a zero value, either via v1 or
   139  	//  v1beta3 (with the roundtrip annotation) for the
   140  	//  'nominalConcurrencyShares' field of 'limited' for UPDATE operation,
   141  	//  only if the existing object already contains a zero value.
   142  	//  1:30: lift this restriction, allow zero value via v1 or v1beta3
   143  	opts := validation.PriorityLevelValidationOptions{
   144  		AllowZeroLimitedNominalConcurrencyShares: true,
   145  	}
   146  	return validation.ValidatePriorityLevelConfiguration(newPL, getRequestGroupVersion(ctx), opts)
   147  }
   148  
   149  // WarningsOnUpdate returns warnings for the given update.
   150  func (priorityLevelConfigurationStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string {
   151  	return nil
   152  }
   153  
   154  type priorityLevelConfigurationStatusStrategy struct {
   155  	priorityLevelConfigurationStrategy
   156  }
   157  
   158  // StatusStrategy is the default logic that applies when updating priority level configuration objects' status.
   159  var StatusStrategy = priorityLevelConfigurationStatusStrategy{Strategy}
   160  
   161  // GetResetFields returns the set of fields that get reset by the strategy
   162  // and should not be modified by the user.
   163  func (priorityLevelConfigurationStatusStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
   164  	fields := map[fieldpath.APIVersion]*fieldpath.Set{
   165  		"flowcontrol.apiserver.k8s.io/v1beta1": fieldpath.NewSet(
   166  			fieldpath.MakePathOrDie("spec"),
   167  			fieldpath.MakePathOrDie("metadata"),
   168  		),
   169  		"flowcontrol.apiserver.k8s.io/v1beta2": fieldpath.NewSet(
   170  			fieldpath.MakePathOrDie("spec"),
   171  			fieldpath.MakePathOrDie("metadata"),
   172  		),
   173  		"flowcontrol.apiserver.k8s.io/v1beta3": fieldpath.NewSet(
   174  			fieldpath.MakePathOrDie("spec"),
   175  			fieldpath.MakePathOrDie("metadata"),
   176  		),
   177  		"flowcontrol.apiserver.k8s.io/v1": fieldpath.NewSet(
   178  			fieldpath.MakePathOrDie("spec"),
   179  			fieldpath.MakePathOrDie("metadata"),
   180  		),
   181  	}
   182  
   183  	return fields
   184  }
   185  
   186  func (priorityLevelConfigurationStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
   187  	newPriorityLevelConfiguration := obj.(*flowcontrol.PriorityLevelConfiguration)
   188  	oldPriorityLevelConfiguration := old.(*flowcontrol.PriorityLevelConfiguration)
   189  
   190  	// managedFields must be preserved since it's been modified to
   191  	// track changed fields in the status update.
   192  	managedFields := newPriorityLevelConfiguration.ManagedFields
   193  	newPriorityLevelConfiguration.ObjectMeta = oldPriorityLevelConfiguration.ObjectMeta
   194  	newPriorityLevelConfiguration.ManagedFields = managedFields
   195  	newPriorityLevelConfiguration.Spec = oldPriorityLevelConfiguration.Spec
   196  }
   197  
   198  func (priorityLevelConfigurationStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
   199  	return validation.ValidatePriorityLevelConfigurationStatusUpdate(old.(*flowcontrol.PriorityLevelConfiguration), obj.(*flowcontrol.PriorityLevelConfiguration))
   200  }
   201  
   202  // WarningsOnUpdate returns warnings for the given update.
   203  func (priorityLevelConfigurationStatusStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string {
   204  	return nil
   205  }
   206  
   207  func getRequestGroupVersion(ctx context.Context) schema.GroupVersion {
   208  	if requestInfo, exists := genericapirequest.RequestInfoFrom(ctx); exists {
   209  		return schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
   210  	}
   211  	return schema.GroupVersion{}
   212  }
   213  

View as plain text