diff --git a/pkg/api/helpers.go b/pkg/api/helpers.go index 4ada0ba3..4705e11f 100644 --- a/pkg/api/helpers.go +++ b/pkg/api/helpers.go @@ -465,6 +465,44 @@ const ( ObjectTTLAnnotationKey string = "node.alpha.kubernetes.io/ttl" ) +// AddOrUpdateTolerationInPod tries to add a toleration to the pod's toleration list. +// Returns true if something was updated, false otherwise. +func AddOrUpdateTolerationInPod(pod *Pod, toleration *Toleration) (bool, error) { + podTolerations := pod.Spec.Tolerations + + var newTolerations []Toleration + updated := false + for i := range podTolerations { + if toleration.MatchToleration(&podTolerations[i]) { + if Semantic.DeepEqual(toleration, podTolerations[i]) { + return false, nil + } + newTolerations = append(newTolerations, *toleration) + updated = true + continue + } + + newTolerations = append(newTolerations, podTolerations[i]) + } + + if !updated { + newTolerations = append(newTolerations, *toleration) + } + + pod.Spec.Tolerations = newTolerations + return true, nil +} + +// MatchToleration checks if the toleration matches tolerationToMatch. Tolerations are unique by , +// if the two tolerations have same combination, regard as they match. +// TODO: uniqueness check for tolerations in api validations. +func (t *Toleration) MatchToleration(tolerationToMatch *Toleration) bool { + return t.Key == tolerationToMatch.Key && + t.Effect == tolerationToMatch.Effect && + t.Operator == tolerationToMatch.Operator && + t.Value == tolerationToMatch.Value +} + // TolerationToleratesTaint checks if the toleration tolerates the taint. func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool { if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {