...

Source file src/k8s.io/kubernetes/pkg/registry/resource/resourceslice/strategy.go

Documentation: k8s.io/kubernetes/pkg/registry/resource/resourceslice

     1  /*
     2  Copyright 2022 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 resourceslice
    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  	"k8s.io/client-go/tools/cache"
    31  	"k8s.io/kubernetes/pkg/api/legacyscheme"
    32  	"k8s.io/kubernetes/pkg/apis/resource"
    33  	"k8s.io/kubernetes/pkg/apis/resource/validation"
    34  )
    35  
    36  // resourceSliceStrategy implements behavior for ResourceSlice objects
    37  type resourceSliceStrategy struct {
    38  	runtime.ObjectTyper
    39  	names.NameGenerator
    40  }
    41  
    42  var Strategy = resourceSliceStrategy{legacyscheme.Scheme, names.SimpleNameGenerator}
    43  
    44  func (resourceSliceStrategy) NamespaceScoped() bool {
    45  	return false
    46  }
    47  
    48  func (resourceSliceStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
    49  }
    50  
    51  func (resourceSliceStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
    52  	slice := obj.(*resource.ResourceSlice)
    53  	return validation.ValidateResourceSlice(slice)
    54  }
    55  
    56  func (resourceSliceStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string {
    57  	return nil
    58  }
    59  
    60  func (resourceSliceStrategy) Canonicalize(obj runtime.Object) {
    61  }
    62  
    63  func (resourceSliceStrategy) AllowCreateOnUpdate() bool {
    64  	return false
    65  }
    66  
    67  func (resourceSliceStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
    68  }
    69  
    70  func (resourceSliceStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
    71  	return validation.ValidateResourceSliceUpdate(obj.(*resource.ResourceSlice), old.(*resource.ResourceSlice))
    72  }
    73  
    74  func (resourceSliceStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string {
    75  	return nil
    76  }
    77  
    78  func (resourceSliceStrategy) AllowUnconditionalUpdate() bool {
    79  	return true
    80  }
    81  
    82  var TriggerFunc = map[string]storage.IndexerFunc{
    83  	// Only one index is supported:
    84  	// https://github.com/kubernetes/kubernetes/blob/3aa8c59fec0bf339e67ca80ea7905c817baeca85/staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go#L346-L350
    85  	"nodeName": nodeNameTriggerFunc,
    86  }
    87  
    88  func nodeNameTriggerFunc(obj runtime.Object) string {
    89  	return obj.(*resource.ResourceSlice).NodeName
    90  }
    91  
    92  // Indexers returns the indexers for ResourceSlice.
    93  func Indexers() *cache.Indexers {
    94  	return &cache.Indexers{
    95  		storage.FieldIndex("nodeName"): nodeNameIndexFunc,
    96  	}
    97  }
    98  
    99  func nodeNameIndexFunc(obj interface{}) ([]string, error) {
   100  	slice, ok := obj.(*resource.ResourceSlice)
   101  	if !ok {
   102  		return nil, fmt.Errorf("not a ResourceSlice")
   103  	}
   104  	return []string{slice.NodeName}, nil
   105  }
   106  
   107  // GetAttrs returns labels and fields of a given object for filtering purposes.
   108  func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
   109  	slice, ok := obj.(*resource.ResourceSlice)
   110  	if !ok {
   111  		return nil, nil, fmt.Errorf("not a ResourceSlice")
   112  	}
   113  	return labels.Set(slice.ObjectMeta.Labels), toSelectableFields(slice), nil
   114  }
   115  
   116  // Match returns a generic matcher for a given label and field selector.
   117  func Match(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
   118  	return storage.SelectionPredicate{
   119  		Label:       label,
   120  		Field:       field,
   121  		GetAttrs:    GetAttrs,
   122  		IndexFields: []string{"nodeName"},
   123  	}
   124  }
   125  
   126  // toSelectableFields returns a field set that represents the object
   127  // TODO: fields are not labels, and the validation rules for them do not apply.
   128  func toSelectableFields(slice *resource.ResourceSlice) fields.Set {
   129  	// The purpose of allocation with a given number of elements is to reduce
   130  	// amount of allocations needed to create the fields.Set. If you add any
   131  	// field here or the number of object-meta related fields changes, this should
   132  	// be adjusted.
   133  	fields := make(fields.Set, 3)
   134  	fields["nodeName"] = slice.NodeName
   135  	fields["driverName"] = slice.DriverName
   136  
   137  	// Adds one field.
   138  	return generic.AddObjectMetaFieldsSet(fields, &slice.ObjectMeta, false)
   139  }
   140  

View as plain text