knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/kmeta/labels.go (about) 1 /* 2 Copyright 2018 The Knative 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 kmeta 18 19 import ( 20 "fmt" 21 22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 "k8s.io/apimachinery/pkg/labels" 24 "k8s.io/apimachinery/pkg/selection" 25 ) 26 27 // The methods in this file are used for managing subresources in cases where 28 // a controller instantiates different resources for each version of itself. 29 // There are two sets of methods available here: 30 // * `*VersionLabel*`: these methods act on `metadata.resourceVersion` and 31 // create new labels for EVERY change to the resource (incl. `/status`). 32 // * `*GenerationLabel*`: these methods act on `metadata.generation` and 33 // create new labels for changes to the resource's "spec" (typically, but 34 // some K8s resources change `metadata.generation` for annotations as well 35 // e.g. Deployment). 36 // 37 // For example, if an A might instantiate N B's at version 1 and M B's at 38 // version 2 then it can use MakeVersionLabels to decorate each subresource 39 // with the appropriate labels for the version at which it was instantiated. 40 // 41 // During reconciliation, MakeVersionLabelSelector can be used with the 42 // informer listers to access the appropriate subresources for the current 43 // version of the parent resource. 44 // 45 // Likewise during reconciliation, MakeOldVersionLabelSelector can be used 46 // with the API client's DeleteCollection method to clean up subresources 47 // for older versions of the resource. 48 49 // MakeVersionLabels constructs a set of labels to apply to subresources 50 // instantiated at this version of the parent resource, so that we can 51 // efficiently select them. 52 func MakeVersionLabels(om metav1.ObjectMetaAccessor) labels.Set { 53 return map[string]string{ 54 "controller": string(om.GetObjectMeta().GetUID()), 55 "version": om.GetObjectMeta().GetResourceVersion(), 56 } 57 } 58 59 // MakeVersionLabelSelector constructs a selector for subresources 60 // instantiated at this version of the parent resource. This keys 61 // off of the labels populated by MakeVersionLabels. 62 func MakeVersionLabelSelector(om metav1.ObjectMetaAccessor) labels.Selector { 63 return labels.SelectorFromSet(MakeVersionLabels(om)) 64 } 65 66 // MakeOldVersionLabelSelector constructs a selector for subresources 67 // instantiated at an older version of the parent resource. This keys 68 // off of the labels populated by MakeVersionLabels. 69 func MakeOldVersionLabelSelector(om metav1.ObjectMetaAccessor) labels.Selector { 70 return labels.NewSelector().Add( 71 mustNewRequirement("controller", selection.Equals, []string{string(om.GetObjectMeta().GetUID())}), 72 mustNewRequirement("version", selection.NotEquals, []string{om.GetObjectMeta().GetResourceVersion()}), 73 ) 74 } 75 76 // MakeGenerationLabels constructs a set of labels to apply to subresources 77 // instantiated at this version of the parent resource, so that we can 78 // efficiently select them. 79 func MakeGenerationLabels(om metav1.ObjectMetaAccessor) labels.Set { 80 return map[string]string{ 81 "controller": string(om.GetObjectMeta().GetUID()), 82 "generation": genStr(om), 83 } 84 } 85 86 // MakeGenerationLabelSelector constructs a selector for subresources 87 // instantiated at this version of the parent resource. This keys 88 // off of the labels populated by MakeGenerationLabels. 89 func MakeGenerationLabelSelector(om metav1.ObjectMetaAccessor) labels.Selector { 90 return labels.SelectorFromSet(MakeGenerationLabels(om)) 91 } 92 93 // MakeOldGenerationLabelSelector constructs a selector for subresources 94 // instantiated at an older version of the parent resource. This keys 95 // off of the labels populated by MakeGenerationLabels. 96 func MakeOldGenerationLabelSelector(om metav1.ObjectMetaAccessor) labels.Selector { 97 return labels.NewSelector().Add( 98 mustNewRequirement("controller", selection.Equals, []string{string(om.GetObjectMeta().GetUID())}), 99 mustNewRequirement("generation", selection.NotEquals, []string{genStr(om)}), 100 ) 101 } 102 103 func genStr(om metav1.ObjectMetaAccessor) string { 104 return fmt.Sprintf("%05d", om.GetObjectMeta().GetGeneration()) 105 } 106 107 // mustNewRequirement panics if there are any errors constructing our selectors. 108 func mustNewRequirement(key string, op selection.Operator, vals []string) labels.Requirement { 109 r, err := labels.NewRequirement(key, op, vals) 110 if err != nil { 111 panic(fmt.Sprintf("mustNewRequirement(%v, %v, %v) = %v", key, op, vals, err)) 112 } 113 return *r 114 }