diff --git a/pkg/canary/config_tracker.go b/pkg/canary/config_tracker.go index 23e80feb..fafc5af9 100644 --- a/pkg/canary/config_tracker.go +++ b/pkg/canary/config_tracker.go @@ -438,5 +438,29 @@ func (ct *ConfigTracker) ApplyPrimaryConfigs(spec corev1.PodSpec, refs map[strin } } + // update affinity + if affinity := spec.Affinity; affinity != nil { + if podAntiAffinity := affinity.PodAntiAffinity; podAntiAffinity != nil { + for _, preferredAntiAffinity := range podAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution { + term := preferredAntiAffinity.PodAffinityTerm + appendPrimarySuffixToValuesIfNeeded(term.TopologyKey, term.LabelSelector) + } + + for _, requiredAntiAffinity := range podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution { + appendPrimarySuffixToValuesIfNeeded(requiredAntiAffinity.TopologyKey, requiredAntiAffinity.LabelSelector) + } + } + } + return spec } + +func appendPrimarySuffixToValuesIfNeeded(topologyKey string, labelSelector *metav1.LabelSelector) { + if labelSelector != nil && topologyKey == "failure-domain.beta.kubernetes.io/zone" { + for _, matchExpression := range labelSelector.MatchExpressions { + for i := range matchExpression.Values { + matchExpression.Values[i] += "-primary" + } + } + } +} diff --git a/pkg/canary/config_tracker_test.go b/pkg/canary/config_tracker_test.go index 3399db95..d30ea1b0 100644 --- a/pkg/canary/config_tracker_test.go +++ b/pkg/canary/config_tracker_test.go @@ -39,6 +39,23 @@ func TestConfigIsDisabled(t *testing.T) { } } +func TestConfigTracker_AntiAffinity(t *testing.T) { + t.Run("deployment", func(t *testing.T) { + dc := deploymentConfigs{name: "podinfo", label: "name", labelValue: "podinfo"} + mocks := newDeploymentFixture(dc) + mocks.initializeCanary(t) + + depPrimary, err := mocks.kubeClient.AppsV1().Deployments("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{}) + require.NoError(t, err) + + value := depPrimary.Spec.Template.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.LabelSelector.MatchExpressions[0].Values[0] + assert.Equal(t, "podinfo-primary", value) + + value = depPrimary.Spec.Template.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].LabelSelector.MatchExpressions[0].Values[0] + assert.Equal(t, "podinfo-primary", value) + }) +} + func TestConfigTracker_ConfigMaps(t *testing.T) { t.Run("deployment", func(t *testing.T) { dc := deploymentConfigs{name: "podinfo", label: "name", labelValue: "podinfo"} diff --git a/pkg/canary/deployment_fixture_test.go b/pkg/canary/deployment_fixture_test.go index da423fd7..997e5c1f 100644 --- a/pkg/canary/deployment_fixture_test.go +++ b/pkg/canary/deployment_fixture_test.go @@ -556,6 +556,36 @@ func newDeploymentControllerTest(dc deploymentConfigs) *appsv1.Deployment { }, }, }, + Affinity: &corev1.Affinity{ + PodAntiAffinity: &corev1.PodAntiAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.WeightedPodAffinityTerm{ + { + PodAffinityTerm: corev1.PodAffinityTerm{ + TopologyKey: "failure-domain.beta.kubernetes.io/zone", + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Values: []string{"podinfo"}, + }, + }, + }, + }, + }, + }, + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ + { + TopologyKey: "failure-domain.beta.kubernetes.io/zone", + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Values: []string{"podinfo"}, + }, + }, + }, + }, + }, + }, + }, }, }, },