| /* |
| Copyright 2019 Bloomberg Finance LP. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| package util |
| |
| import ( |
| "github.com/go-logr/logr" |
| appsv1 "k8s.io/api/apps/v1" |
| corev1 "k8s.io/api/core/v1" |
| extv1 "k8s.io/api/extensions/v1beta1" |
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| "reflect" |
| "strconv" |
| "strings" |
| ) |
| |
| // CopyLabelsAndAnnotations copies the labels and annotations from one object to another. |
| // Additional Labels and Annotations in the 'to' object will not be removed. |
| // Returns true if there are updates required to the object. |
| func CopyLabelsAndAnnotations(from, to *metav1.ObjectMeta, logger logr.Logger) (requireUpdate bool) { |
| if len(to.Labels) == 0 && len(from.Labels) > 0 { |
| to.Labels = make(map[string]string, len(from.Labels)) |
| } |
| for k, v := range from.Labels { |
| if to.Labels[k] != v { |
| requireUpdate = true |
| logger.Info("Update Label", "label", k, "newValue", v, "oldValue", to.Labels[k]) |
| to.Labels[k] = v |
| } |
| } |
| |
| if len(to.Annotations) == 0 && len(from.Annotations) > 0 { |
| to.Annotations = make(map[string]string, len(from.Annotations)) |
| } |
| for k, v := range from.Annotations { |
| if to.Annotations[k] != v { |
| requireUpdate = true |
| logger.Info("Update Annotation", "annotation", k, "newValue", v, "oldValue", to.Annotations[k]) |
| to.Annotations[k] = v |
| } |
| } |
| |
| return requireUpdate |
| } |
| |
| func DuplicateLabelsOrAnnotations(from map[string]string) map[string]string { |
| to := make(map[string]string, len(from)) |
| for k, v := range from { |
| to[k] = v |
| } |
| return to |
| } |
| |
| func MergeLabelsOrAnnotations(base, additional map[string]string) map[string]string { |
| merged := DuplicateLabelsOrAnnotations(base) |
| for k, v := range additional { |
| if _, alreadyExists := merged[k]; !alreadyExists { |
| merged[k] = v |
| } |
| } |
| return merged |
| } |
| |
| // DeepEqualWithNils returns a deepEquals call that treats nil and zero-length maps, arrays and slices as the same. |
| func DeepEqualWithNils(x, y interface{}) bool { |
| if (x == nil) != (y == nil) { |
| // Make sure that x is not the nil value |
| if x == nil { |
| x = y |
| } |
| v := reflect.ValueOf(x) |
| switch v.Kind() { |
| case reflect.Array: |
| case reflect.Map: |
| case reflect.Slice: |
| return v.Len() == 0 |
| } |
| } |
| return reflect.DeepEqual(x, y) |
| } |
| |
| // ContainsString helper function to test string contains |
| func ContainsString(slice []string, s string) bool { |
| for _, item := range slice { |
| if item == s { |
| return true |
| } |
| } |
| return false |
| } |
| |
| // RemoveString helper function to remove string |
| func RemoveString(slice []string, s string) (result []string) { |
| for _, item := range slice { |
| if item == s { |
| continue |
| } |
| result = append(result, item) |
| } |
| return |
| } |
| |
| // IsPVCOrphan determines whether the given name represents a PVC that is an orphan, or no longer has a pod associated with it. |
| func IsPVCOrphan(pvcName string, replicas int32) bool { |
| index := strings.LastIndexAny(pvcName, "-") |
| if index == -1 { |
| return false |
| } |
| |
| ordinal, err := strconv.Atoi(pvcName[index+1:]) |
| if err != nil { |
| return false |
| } |
| |
| return int32(ordinal) >= replicas |
| } |
| |
| // CopyConfigMapFields copies the owned fields from one ConfigMap to another |
| func CopyConfigMapFields(from, to *corev1.ConfigMap, logger logr.Logger) bool { |
| logger = logger.WithValues("kind", "configMap") |
| requireUpdate := CopyLabelsAndAnnotations(&from.ObjectMeta, &to.ObjectMeta, logger) |
| |
| // Don't copy the entire Spec, because we can't overwrite the clusterIp field |
| |
| if !DeepEqualWithNils(to.Data, from.Data) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Data", "from", to.Data, "to", from.Data) |
| } |
| to.Data = from.Data |
| |
| return requireUpdate |
| } |
| |
| // CopyServiceFields copies the owned fields from one Service to another |
| func CopyServiceFields(from, to *corev1.Service, logger logr.Logger) bool { |
| logger = logger.WithValues("kind", "service") |
| requireUpdate := CopyLabelsAndAnnotations(&from.ObjectMeta, &to.ObjectMeta, logger) |
| |
| // Don't copy the entire Spec, because we can't overwrite the clusterIp field |
| |
| if !DeepEqualWithNils(to.Spec.Selector, from.Spec.Selector) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.Selector", "from", to.Spec.Selector, "to", from.Spec.Selector) |
| } |
| to.Spec.Selector = from.Spec.Selector |
| |
| if !DeepEqualWithNils(to.Spec.Ports, from.Spec.Ports) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.Ports", "from", to.Spec.Ports, "to", from.Spec.Ports) |
| } |
| to.Spec.Ports = from.Spec.Ports |
| |
| if !DeepEqualWithNils(to.Spec.ExternalName, from.Spec.ExternalName) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.ExternalName", "from", to.Spec.ExternalName, "to", from.Spec.ExternalName) |
| } |
| to.Spec.ExternalName = from.Spec.ExternalName |
| |
| if !DeepEqualWithNils(to.Spec.PublishNotReadyAddresses, from.Spec.PublishNotReadyAddresses) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.PublishNotReadyAddresses", "from", to.Spec.PublishNotReadyAddresses, "to", from.Spec.PublishNotReadyAddresses) |
| } |
| to.Spec.PublishNotReadyAddresses = from.Spec.PublishNotReadyAddresses |
| |
| return requireUpdate |
| } |
| |
| // CopyIngressFields copies the owned fields from one Ingress to another |
| func CopyIngressFields(from, to *extv1.Ingress, logger logr.Logger) bool { |
| logger = logger.WithValues("kind", "ingress") |
| requireUpdate := CopyLabelsAndAnnotations(&from.ObjectMeta, &to.ObjectMeta, logger) |
| |
| if len(to.Spec.Rules) != len(from.Spec.Rules) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.Rules", "from", to.Spec.Rules, "to", from.Spec.Rules) |
| to.Spec.Rules = from.Spec.Rules |
| } else { |
| for i := range from.Spec.Rules { |
| ruleBase := "Spec.Rules["+strconv.Itoa(i)+"]." |
| fromRule := &from.Spec.Rules[i] |
| toRule := &to.Spec.Rules[i] |
| |
| if !DeepEqualWithNils(toRule.Host, fromRule.Host) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", ruleBase+"Host", "from", toRule.Host, "to", fromRule.Host) |
| toRule.Host = fromRule.Host |
| } |
| |
| if fromRule.HTTP == nil || toRule.HTTP == nil { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", ruleBase+"HTTP", "from", toRule.HTTP, "to", fromRule.HTTP) |
| toRule.HTTP = fromRule.HTTP |
| } else if len(fromRule.HTTP.Paths) != len(toRule.HTTP.Paths) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", ruleBase+"HTTP.Paths", "from", toRule.HTTP.Paths, "to", fromRule.HTTP.Paths) |
| toRule.HTTP.Paths = fromRule.HTTP.Paths |
| } else { |
| for j := range fromRule.HTTP.Paths { |
| pathBase := ruleBase+"HTTP.Paths["+strconv.Itoa(j)+"]." |
| fromPath := &fromRule.HTTP.Paths[j] |
| toPath := &toRule.HTTP.Paths[j] |
| |
| if toPath.PathType != nil && !DeepEqualWithNils(toPath.PathType, fromPath.PathType) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", pathBase+"PathType", "from", toPath.PathType, "to", fromPath.PathType) |
| toPath.PathType = fromPath.PathType |
| } |
| |
| if !DeepEqualWithNils(toPath.Path, fromPath.Path) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", pathBase+"Path", "from", toPath.Path, "to", fromPath.Path) |
| toPath.Path = fromPath.Path |
| } |
| |
| if !DeepEqualWithNils(toPath.Backend.ServiceName, fromPath.Backend.ServiceName) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", pathBase+"Backend.ServiceName", "from", toPath.Backend.ServiceName, "to", fromPath.Backend.ServiceName) |
| toPath.Backend.ServiceName = fromPath.Backend.ServiceName |
| } |
| |
| if !DeepEqualWithNils(toPath.Backend.ServicePort, fromPath.Backend.ServicePort) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", pathBase+"Backend.ServicePort", "from", toPath.Backend.ServicePort, "to", fromPath.Backend.ServicePort) |
| toPath.Backend.ServicePort = fromPath.Backend.ServicePort |
| } |
| |
| if !DeepEqualWithNils(toPath.Backend.Resource, fromPath.Backend.Resource) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", pathBase+"Backend.Resource", "from", toPath.Backend.Resource, "to", fromPath.Backend.Resource) |
| toPath.Backend.Resource = fromPath.Backend.Resource |
| } |
| } |
| } |
| } |
| } |
| |
| return requireUpdate |
| } |
| |
| // CopyStatefulSetFields copies the owned fields from one StatefulSet to another |
| // Returns true if the fields copied from don't match to. |
| func CopyStatefulSetFields(from, to *appsv1.StatefulSet, logger logr.Logger) bool { |
| logger = logger.WithValues("kind", "statefulSet") |
| requireUpdate := CopyLabelsAndAnnotations(&from.ObjectMeta, &to.ObjectMeta, logger) |
| |
| if !DeepEqualWithNils(to.Spec.Replicas, from.Spec.Replicas) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.Replicas", "from", to.Spec.Replicas, "to", from.Spec.Replicas) |
| to.Spec.Replicas = from.Spec.Replicas |
| } |
| |
| if !DeepEqualWithNils(to.Spec.UpdateStrategy, from.Spec.UpdateStrategy) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.UpdateStrategy", "from", to.Spec.UpdateStrategy, "to", from.Spec.UpdateStrategy) |
| to.Spec.UpdateStrategy = from.Spec.UpdateStrategy |
| } |
| |
| /* |
| Kubernetes does not currently support updates to these fields: Selector and PodManagementPolicy |
| |
| if !DeepEqualWithNils(to.Spec.Selector, from.Spec.Selector) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.Selector", "from", to.Spec.Selector, "to", from.Spec.Selector) |
| to.Spec.Selector = from.Spec.Selector |
| } |
| |
| if !DeepEqualWithNils(to.Spec.PodManagementPolicy, from.Spec.PodManagementPolicy) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.PodManagementPolicy", "from", to.Spec.PodManagementPolicy, "to", from.Spec.PodManagementPolicy) |
| to.Spec.PodManagementPolicy = from.Spec.PodManagementPolicy |
| } |
| */ |
| |
| /* |
| Kubernetes does not support modification of VolumeClaimTemplates currently. See: |
| https://github.com/kubernetes/enhancements/issues/661 |
| |
| if len(from.Spec.VolumeClaimTemplates) > len(to.Spec.VolumeClaimTemplates) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.VolumeClaimTemplates", "from", to.Spec.VolumeClaimTemplates, "to", from.Spec.VolumeClaimTemplates) |
| to.Spec.VolumeClaimTemplates = from.Spec.VolumeClaimTemplates |
| } |
| for i := range from.Spec.VolumeClaimTemplates { |
| vctBase := "Spec.VolumeClaimTemplates["+strconv.Itoa(i)+"]." |
| fromVct := &from.Spec.VolumeClaimTemplates[i] |
| toVct := &to.Spec.VolumeClaimTemplates[i] |
| if !DeepEqualWithNils(to.Spec.VolumeClaimTemplates[i].Name, fromVct.Name) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", vctBase+"Name", "from", toVct.Name, "to", fromVct.Name) |
| toVct.Name = fromVct.Name |
| } |
| if !DeepEqualWithNils(to.Spec.VolumeClaimTemplates[i].Labels, fromVct.Labels) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", vctBase+"Labels", "from", toVct.Labels, "to", fromVct.Labels) |
| toVct.Labels = fromVct.Labels |
| } |
| if !DeepEqualWithNils(to.Spec.VolumeClaimTemplates[i].Annotations, fromVct.Annotations) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", vctBase+"Annotations", "from", toVct.Annotations, "to", fromVct.Annotations) |
| toVct.Annotations = fromVct.Annotations |
| } |
| if !DeepEqualWithNils(to.Spec.VolumeClaimTemplates[i].Spec, fromVct.Spec) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", vctBase+"Spec", "from", toVct.Spec, "to", fromVct.Spec) |
| toVct.Spec = fromVct.Spec |
| } |
| } |
| */ |
| |
| requireUpdate = requireUpdate || CopyPodTemplates(&from.Spec.Template, &to.Spec.Template, "Spec.Template.", logger) |
| |
| return requireUpdate |
| } |
| |
| // CopyDeploymentFields copies the owned fields from one Deployment to another |
| // Returns true if the fields copied from don't match to. |
| func CopyDeploymentFields(from, to *appsv1.Deployment, logger logr.Logger) bool { |
| logger = logger.WithValues("kind", "deployment") |
| requireUpdate := CopyLabelsAndAnnotations(&from.ObjectMeta, &to.ObjectMeta, logger) |
| |
| if !DeepEqualWithNils(to.Spec.Replicas, from.Spec.Replicas) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.Replicas", "from", to.Spec.Replicas, "to", from.Spec.Replicas) |
| to.Spec.Replicas = from.Spec.Replicas |
| } |
| |
| if !DeepEqualWithNils(to.Spec.Selector, from.Spec.Selector) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", "Spec.Selector", "from", to.Spec.Selector, "to", from.Spec.Selector) |
| to.Spec.Selector = from.Spec.Selector |
| } |
| |
| requireUpdate = requireUpdate || CopyPodTemplates(&from.Spec.Template, &to.Spec.Template, "Spec.Template.", logger) |
| |
| return requireUpdate |
| } |
| |
| func CopyPodTemplates(from, to *corev1.PodTemplateSpec, basePath string, logger logr.Logger) (requireUpdate bool) { |
| if basePath == "" { |
| logger = logger.WithValues("kind", "pod") |
| } |
| if !DeepEqualWithNils(to.Labels, from.Labels) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", basePath+"Labels", "from", to.Labels, "to", from.Labels) |
| to.Labels = from.Labels |
| } |
| |
| if !DeepEqualWithNils(to.Annotations, from.Annotations) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", basePath+"Annotations", "from", to.Annotations, "to", from.Annotations) |
| to.Annotations = from.Annotations |
| } |
| |
| requireUpdate = requireUpdate || CopyPodContainers(&from.Spec.Containers, &to.Spec.Containers, basePath+"Spec.Containers", logger) |
| |
| requireUpdate = requireUpdate || CopyPodContainers(&from.Spec.InitContainers, &to.Spec.InitContainers, basePath+"Spec.InitContainers", logger) |
| |
| if !DeepEqualWithNils(to.Spec.HostAliases, from.Spec.HostAliases) { |
| requireUpdate = true |
| to.Spec.HostAliases = from.Spec.HostAliases |
| logger.Info("Update required because field changed", "field", basePath+"Spec.HostAliases", "from", to.Spec.HostAliases, "to", from.Spec.HostAliases) |
| } |
| |
| if !DeepEqualWithNils(to.Spec.Volumes, from.Spec.Volumes) { |
| requireUpdate = true |
| to.Spec.Volumes = from.Spec.Volumes |
| logger.Info("Update required because field changed", "field", basePath+"Spec.Volumes", "from", to.Spec.Volumes, "to", from.Spec.Volumes) |
| } |
| |
| if !DeepEqualWithNils(to.Spec.ImagePullSecrets, from.Spec.ImagePullSecrets) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", basePath+"Spec.ImagePullSecrets", "from", to.Spec.ImagePullSecrets, "to", from.Spec.ImagePullSecrets) |
| to.Spec.ImagePullSecrets = from.Spec.ImagePullSecrets |
| } |
| |
| if !DeepEqualWithNils(to.Spec.Affinity, from.Spec.Affinity) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", basePath+"Spec.Affinity", "from", to.Spec.Affinity, "to", from.Spec.Affinity) |
| to.Spec.Affinity = from.Spec.Affinity |
| } |
| |
| if !DeepEqualWithNils(to.Spec.SecurityContext, from.Spec.SecurityContext) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", basePath+"Spec.SecurityContext", "from", to.Spec.SecurityContext, "to", from.Spec.SecurityContext) |
| to.Spec.SecurityContext = from.Spec.SecurityContext |
| } |
| |
| if !DeepEqualWithNils(to.Spec.NodeSelector, from.Spec.NodeSelector) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", basePath+"Spec.NodeSelector", "from", to.Spec.NodeSelector, "to", from.Spec.NodeSelector) |
| to.Spec.NodeSelector = from.Spec.NodeSelector |
| } |
| |
| if !DeepEqualWithNils(to.Spec.Tolerations, from.Spec.Tolerations) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", basePath+"Spec.Tolerations", "from", to.Spec.Tolerations, "to", from.Spec.Tolerations) |
| to.Spec.Tolerations = from.Spec.Tolerations |
| } |
| |
| if !DeepEqualWithNils(to.Spec.PriorityClassName, from.Spec.PriorityClassName) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", basePath+"Spec.PriorityClassName", "from", to.Spec.PriorityClassName, "to", from.Spec.PriorityClassName) |
| to.Spec.PriorityClassName = from.Spec.PriorityClassName |
| } |
| |
| return requireUpdate |
| } |
| |
| func CopyPodContainers(fromPtr, toPtr *[]corev1.Container, basePath string, logger logr.Logger) (requireUpdate bool) { |
| to := *toPtr |
| from := *fromPtr |
| if len(to) < len(from) { |
| requireUpdate = true |
| *toPtr = from |
| } else { |
| for i := 0; i < len(from); i++ { |
| containerBasePath := basePath+"["+strconv.Itoa(i)+"]." |
| if !DeepEqualWithNils(to[i].Name, from[i].Name) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"Name", "from", to[i].Name, "to", from[i].Name) |
| to[i].Name = from[i].Name |
| } |
| |
| if !DeepEqualWithNils(to[i].Image, from[i].Image) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"Image", "from", to[i].Image, "to", from[i].Image) |
| to[i].Image = from[i].Image |
| } |
| |
| if from[i].ImagePullPolicy != "" && !DeepEqualWithNils(to[i].ImagePullPolicy, from[i].ImagePullPolicy) { |
| // Only request an update if the requestedPullPolicy is not empty |
| // Otherwise kubernetes will specify a defaultPollPolicy and the operator will endlessly recurse, trying to unset the default policy. |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"ImagePullPolicy", "from", to[i].ImagePullPolicy, "to", from[i].ImagePullPolicy) |
| } |
| to[i].ImagePullPolicy = from[i].ImagePullPolicy |
| |
| if !DeepEqualWithNils(to[i].Command, from[i].Command) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"Command", "from", to[i].Command, "to", from[i].Command) |
| to[i].Command = from[i].Command |
| } |
| |
| if !DeepEqualWithNils(to[i].Args, from[i].Args) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"Args", "from", to[i].Args, "to", from[i].Args) |
| to[i].Args = from[i].Args |
| } |
| |
| if !DeepEqualWithNils(to[i].Env, from[i].Env) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"Env", "from", to[i].Env, "to", from[i].Env) |
| to[i].Env = from[i].Env |
| } |
| |
| if !DeepEqualWithNils(to[i].Resources, from[i].Resources) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"Resources", "from", to[i].Resources, "to", from[i].Resources) |
| to[i].Resources = from[i].Resources |
| } |
| |
| if !DeepEqualWithNils(to[i].VolumeMounts, from[i].VolumeMounts) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"VolumeMounts", "from", to[i].VolumeMounts, "to", from[i].VolumeMounts) |
| to[i].VolumeMounts = from[i].VolumeMounts |
| } |
| |
| if !DeepEqualWithNils(to[i].Ports, from[i].Ports) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"Ports", "from", to[i].Ports, "to", from[i].Ports) |
| to[i].Ports = from[i].Ports |
| } |
| |
| if !DeepEqualWithNils(to[i].Lifecycle, from[i].Lifecycle) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"Lifecycle", "from", to[i].Lifecycle, "to", from[i].Lifecycle) |
| to[i].Lifecycle = from[i].Lifecycle |
| } |
| |
| if !DeepEqualWithNils(to[i].LivenessProbe, from[i].LivenessProbe) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"LivenessProbe", "from", to[i].LivenessProbe, "to", from[i].LivenessProbe) |
| to[i].LivenessProbe = from[i].LivenessProbe |
| } |
| |
| if !DeepEqualWithNils(to[i].ReadinessProbe, from[i].ReadinessProbe) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"ReadinessProbe", "from", to[i].ReadinessProbe, "to", from[i].ReadinessProbe) |
| to[i].LivenessProbe = from[i].ReadinessProbe |
| } |
| |
| if !DeepEqualWithNils(to[i].StartupProbe, from[i].StartupProbe) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"StartupProbe", "from", to[i].StartupProbe, "to", from[i].StartupProbe) |
| to[i].StartupProbe = from[i].StartupProbe |
| } |
| |
| if from[i].TerminationMessagePath != "" && !DeepEqualWithNils(to[i].TerminationMessagePath, from[i].TerminationMessagePath) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"TerminationMessagePath", "from", to[i].TerminationMessagePath, "to", from[i].TerminationMessagePath) |
| to[i].TerminationMessagePath = from[i].TerminationMessagePath |
| } |
| |
| if from[i].TerminationMessagePolicy != "" && !DeepEqualWithNils(to[i].TerminationMessagePolicy, from[i].TerminationMessagePolicy) { |
| requireUpdate = true |
| logger.Info("Update required because field changed", "field", containerBasePath+"TerminationMessagePolicy", "from", to[i].TerminationMessagePolicy, "to", from[i].TerminationMessagePolicy) |
| to[i].TerminationMessagePolicy = from[i].TerminationMessagePolicy |
| } |
| } |
| } |
| return requireUpdate |
| } |