k8s.io/kubernetes@v1.29.3/pkg/registry/resource/resourceclaim/strategy.go (about) 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 resourceclaim 18 19 import ( 20 "context" 21 "errors" 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/kubernetes/pkg/api/legacyscheme" 31 "k8s.io/kubernetes/pkg/apis/resource" 32 "k8s.io/kubernetes/pkg/apis/resource/validation" 33 "sigs.k8s.io/structured-merge-diff/v4/fieldpath" 34 ) 35 36 // resourceclaimStrategy implements behavior for ResourceClaim objects 37 type resourceclaimStrategy struct { 38 runtime.ObjectTyper 39 names.NameGenerator 40 } 41 42 // Strategy is the default logic that applies when creating and updating 43 // ResourceClaim objects via the REST API. 44 var Strategy = resourceclaimStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} 45 46 func (resourceclaimStrategy) NamespaceScoped() bool { 47 return true 48 } 49 50 // GetResetFields returns the set of fields that get reset by the strategy and 51 // should not be modified by the user. For a new ResourceClaim that is the 52 // status. 53 func (resourceclaimStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set { 54 fields := map[fieldpath.APIVersion]*fieldpath.Set{ 55 "resource.k8s.io/v1alpha2": fieldpath.NewSet( 56 fieldpath.MakePathOrDie("status"), 57 ), 58 } 59 60 return fields 61 } 62 63 func (resourceclaimStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { 64 claim := obj.(*resource.ResourceClaim) 65 // Status must not be set by user on create. 66 claim.Status = resource.ResourceClaimStatus{} 67 } 68 69 func (resourceclaimStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { 70 claim := obj.(*resource.ResourceClaim) 71 return validation.ValidateClaim(claim) 72 } 73 74 func (resourceclaimStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { 75 return nil 76 } 77 78 func (resourceclaimStrategy) Canonicalize(obj runtime.Object) { 79 } 80 81 func (resourceclaimStrategy) AllowCreateOnUpdate() bool { 82 return false 83 } 84 85 func (resourceclaimStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { 86 newClaim := obj.(*resource.ResourceClaim) 87 oldClaim := old.(*resource.ResourceClaim) 88 newClaim.Status = oldClaim.Status 89 } 90 91 func (resourceclaimStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { 92 newClaim := obj.(*resource.ResourceClaim) 93 oldClaim := old.(*resource.ResourceClaim) 94 errorList := validation.ValidateClaim(newClaim) 95 return append(errorList, validation.ValidateClaimUpdate(newClaim, oldClaim)...) 96 } 97 98 func (resourceclaimStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { 99 return nil 100 } 101 102 func (resourceclaimStrategy) AllowUnconditionalUpdate() bool { 103 return true 104 } 105 106 type resourceclaimStatusStrategy struct { 107 resourceclaimStrategy 108 } 109 110 var StatusStrategy = resourceclaimStatusStrategy{Strategy} 111 112 // GetResetFields returns the set of fields that get reset by the strategy and 113 // should not be modified by the user. For a status update that is the spec. 114 func (resourceclaimStatusStrategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set { 115 fields := map[fieldpath.APIVersion]*fieldpath.Set{ 116 "resource.k8s.io/v1alpha2": fieldpath.NewSet( 117 fieldpath.MakePathOrDie("spec"), 118 ), 119 } 120 121 return fields 122 } 123 124 func (resourceclaimStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { 125 newClaim := obj.(*resource.ResourceClaim) 126 oldClaim := old.(*resource.ResourceClaim) 127 newClaim.Spec = oldClaim.Spec 128 } 129 130 func (resourceclaimStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { 131 newClaim := obj.(*resource.ResourceClaim) 132 oldClaim := old.(*resource.ResourceClaim) 133 return validation.ValidateClaimStatusUpdate(newClaim, oldClaim) 134 } 135 136 // WarningsOnUpdate returns warnings for the given update. 137 func (resourceclaimStatusStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { 138 return nil 139 } 140 141 // Match returns a generic matcher for a given label and field selector. 142 func Match(label labels.Selector, field fields.Selector) storage.SelectionPredicate { 143 return storage.SelectionPredicate{ 144 Label: label, 145 Field: field, 146 GetAttrs: GetAttrs, 147 } 148 } 149 150 // GetAttrs returns labels and fields of a given object for filtering purposes. 151 func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) { 152 claim, ok := obj.(*resource.ResourceClaim) 153 if !ok { 154 return nil, nil, errors.New("not a resourceclaim") 155 } 156 return labels.Set(claim.Labels), toSelectableFields(claim), nil 157 } 158 159 // toSelectableFields returns a field set that represents the object 160 func toSelectableFields(claim *resource.ResourceClaim) fields.Set { 161 fields := generic.ObjectMetaFieldsSet(&claim.ObjectMeta, true) 162 return fields 163 }