k8s.io/kubernetes@v1.29.3/pkg/util/tolerations/tolerations.go (about) 1 /* 2 Copyright 2017 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 tolerations 18 19 import ( 20 apiequality "k8s.io/apimachinery/pkg/api/equality" 21 "k8s.io/klog/v2" 22 api "k8s.io/kubernetes/pkg/apis/core" 23 ) 24 25 // VerifyAgainstWhitelist checks if the provided tolerations 26 // satisfy the provided whitelist and returns true, otherwise returns false 27 func VerifyAgainstWhitelist(tolerations, whitelist []api.Toleration) bool { 28 if len(whitelist) == 0 || len(tolerations) == 0 { 29 return true 30 } 31 32 next: 33 for _, t := range tolerations { 34 for _, w := range whitelist { 35 if isSuperset(w, t) { 36 continue next 37 } 38 } 39 return false 40 } 41 42 return true 43 } 44 45 // MergeTolerations merges two sets of tolerations into one. If one toleration is a superset of 46 // another, only the superset is kept. 47 func MergeTolerations(first, second []api.Toleration) []api.Toleration { 48 all := append(first, second...) 49 var merged []api.Toleration 50 51 next: 52 for i, t := range all { 53 for _, t2 := range merged { 54 if isSuperset(t2, t) { 55 continue next // t is redundant; ignore it 56 } 57 } 58 if i+1 < len(all) { 59 for _, t2 := range all[i+1:] { 60 // If the tolerations are equal, prefer the first. 61 if !apiequality.Semantic.DeepEqual(&t, &t2) && isSuperset(t2, t) { 62 continue next // t is redundant; ignore it 63 } 64 } 65 } 66 merged = append(merged, t) 67 } 68 69 return merged 70 } 71 72 // isSuperset checks whether ss tolerates a superset of t. 73 func isSuperset(ss, t api.Toleration) bool { 74 if apiequality.Semantic.DeepEqual(&t, &ss) { 75 return true 76 } 77 78 if t.Key != ss.Key && 79 // An empty key with Exists operator means match all keys & values. 80 (ss.Key != "" || ss.Operator != api.TolerationOpExists) { 81 return false 82 } 83 84 // An empty effect means match all effects. 85 if t.Effect != ss.Effect && ss.Effect != "" { 86 return false 87 } 88 89 if ss.Effect == api.TaintEffectNoExecute { 90 if ss.TolerationSeconds != nil { 91 if t.TolerationSeconds == nil || 92 *t.TolerationSeconds > *ss.TolerationSeconds { 93 return false 94 } 95 } 96 } 97 98 switch ss.Operator { 99 case api.TolerationOpEqual, "": // empty operator means Equal 100 return t.Operator == api.TolerationOpEqual && t.Value == ss.Value 101 case api.TolerationOpExists: 102 return true 103 default: 104 klog.Errorf("Unknown toleration operator: %s", ss.Operator) 105 return false 106 } 107 }