Merge pull request #788 from Nerja/podantiaffinityfix

Support for adding -primary suffix to Anti-Affinity values
This commit is contained in:
Stefan Prodan
2021-01-28 09:16:54 +02:00
committed by GitHub
3 changed files with 125 additions and 2 deletions
+42 -2
View File
@@ -116,7 +116,7 @@ func (c *DeploymentController) Promote(cd *flaggerv1.Canary) error {
primaryCopy.Spec.Strategy = canary.Spec.Strategy
// update spec with primary secrets and config maps
primaryCopy.Spec.Template.Spec = c.configTracker.ApplyPrimaryConfigs(canary.Spec.Template.Spec, configRefs)
primaryCopy.Spec.Template.Spec = c.getPrimaryDeploymentTemplateSpec(canary, configRefs)
// update pod annotations to ensure a rolling update
annotations, err := makeAnnotations(canary.Spec.Template.Annotations)
@@ -289,7 +289,7 @@ func (c *DeploymentController) createPrimaryDeployment(cd *flaggerv1.Canary, inc
Annotations: annotations,
},
// update spec with the primary secrets and config maps
Spec: c.configTracker.ApplyPrimaryConfigs(canaryDep.Spec.Template.Spec, configRefs),
Spec: c.getPrimaryDeploymentTemplateSpec(canaryDep, configRefs),
},
},
}
@@ -452,3 +452,43 @@ func (c *DeploymentController) scale(cd *flaggerv1.Canary, replicas int32) error
}
return nil
}
func (c *DeploymentController) getPrimaryDeploymentTemplateSpec(canaryDep *appsv1.Deployment, refs map[string]ConfigRef) corev1.PodSpec {
spec := c.configTracker.ApplyPrimaryConfigs(canaryDep.Spec.Template.Spec, refs)
// update affinity
if affinity := spec.Affinity; affinity != nil {
if podAntiAffinity := affinity.PodAntiAffinity; podAntiAffinity != nil {
for _, preferredAntiAffinity := range podAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution {
c.appendPrimarySuffixToValuesIfNeeded(preferredAntiAffinity.PodAffinityTerm.LabelSelector)
}
for _, requiredAntiAffinity := range podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution {
c.appendPrimarySuffixToValuesIfNeeded(requiredAntiAffinity.LabelSelector)
}
}
}
return spec
}
func (c *DeploymentController) appendPrimarySuffixToValuesIfNeeded(labelSelector *metav1.LabelSelector) {
if labelSelector != nil {
for _, matchExpression := range labelSelector.MatchExpressions {
if contains(c.labels, matchExpression.Key) {
for i := range matchExpression.Values {
matchExpression.Values[i] += "-primary"
}
}
}
}
}
func contains(slice []string, val string) bool {
for _, item := range slice {
if item == val {
return true
}
}
return false
}
+23
View File
@@ -112,6 +112,12 @@ func TestDeploymentController_Promote(t *testing.T) {
hpaPrimary, err := mocks.kubeClient.AutoscalingV2beta2().HorizontalPodAutoscalers("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int32(2), hpaPrimary.Spec.MaxReplicas)
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 TestDeploymentController_ScaleToZero(t *testing.T) {
@@ -256,3 +262,20 @@ func TestDeploymentController_Finalize(t *testing.T) {
require.Equal(t, int32(1), *c.Spec.Replicas)
}
}
func TestDeploymentController_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)
})
}
+60
View File
@@ -556,6 +556,36 @@ func newDeploymentControllerTest(dc deploymentConfigs) *appsv1.Deployment {
},
},
},
Affinity: &corev1.Affinity{
PodAntiAffinity: &corev1.PodAntiAffinity{
PreferredDuringSchedulingIgnoredDuringExecution: []corev1.WeightedPodAffinityTerm{
{
PodAffinityTerm: corev1.PodAffinityTerm{
LabelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "app",
Values: []string{"podinfo"},
},
},
},
},
},
},
RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
{
LabelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "app",
Values: []string{"podinfo"},
},
},
},
},
},
},
},
},
},
},
@@ -757,6 +787,36 @@ func newDeploymentControllerTestV2() *appsv1.Deployment {
},
},
},
Affinity: &corev1.Affinity{
PodAntiAffinity: &corev1.PodAntiAffinity{
PreferredDuringSchedulingIgnoredDuringExecution: []corev1.WeightedPodAffinityTerm{
{
PodAffinityTerm: corev1.PodAffinityTerm{
LabelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "app",
Values: []string{"podinfo"},
},
},
},
},
},
},
RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
{
LabelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: "app",
Values: []string{"podinfo"},
},
},
},
},
},
},
},
},
},
},