You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2021/03/02 13:46:53 UTC

[camel-k] 02/03: Refactor(trait): affinity

This is an automated email from the ASF dual-hosted git repository.

astefanutti pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 489837195caef06b1ecdd9a4f02cceffcd18525f
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Mon Mar 1 16:46:53 2021 +0100

    Refactor(trait): affinity
    
    * Introduced the trait for Knative and CronJob
    
    Closes #2047
---
 pkg/trait/affinity.go      |  45 ++++++-------------
 pkg/trait/affinity_test.go | 109 ++++++++++++++++++++++++++++-----------------
 2 files changed, 81 insertions(+), 73 deletions(-)

diff --git a/pkg/trait/affinity.go b/pkg/trait/affinity.go
index 5c77cf6..aca0e0e 100644
--- a/pkg/trait/affinity.go
+++ b/pkg/trait/affinity.go
@@ -21,7 +21,6 @@ import (
 	"fmt"
 	"strings"
 
-	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
@@ -74,20 +73,19 @@ func (t *affinityTrait) Configure(e *Environment) (bool, error) {
 }
 
 func (t *affinityTrait) Apply(e *Environment) (err error) {
-	var deployment *appsv1.Deployment
-	e.Resources.VisitDeployment(func(d *appsv1.Deployment) {
-		if d.Name == e.Integration.Name {
-			deployment = d
+	podSpec := e.GetIntegrationPodSpec()
+
+	if podSpec != nil {
+		if podSpec.Affinity == nil {
+			podSpec.Affinity = &corev1.Affinity{}
 		}
-	})
-	if deployment != nil {
-		if err := t.addNodeAffinity(e, deployment); err != nil {
+		if err := t.addNodeAffinity(e, podSpec); err != nil {
 			return err
 		}
-		if err := t.addPodAffinity(e, deployment); err != nil {
+		if err := t.addPodAffinity(e, podSpec); err != nil {
 			return err
 		}
-		if err := t.addPodAntiAffinity(e, deployment); err != nil {
+		if err := t.addPodAntiAffinity(e, podSpec); err != nil {
 			return err
 		}
 	}
@@ -95,7 +93,7 @@ func (t *affinityTrait) Apply(e *Environment) (err error) {
 	return nil
 }
 
-func (t *affinityTrait) addNodeAffinity(_ *Environment, deployment *appsv1.Deployment) error {
+func (t *affinityTrait) addNodeAffinity(_ *Environment, podSpec *corev1.PodSpec) error {
 	if len(t.NodeAffinityLabels) == 0 {
 		return nil
 	}
@@ -129,16 +127,11 @@ func (t *affinityTrait) addNodeAffinity(_ *Environment, deployment *appsv1.Deplo
 		},
 	}
 
-	if deployment.Spec.Template.Spec.Affinity == nil {
-		deployment.Spec.Template.Spec.Affinity = &corev1.Affinity{}
-	}
-
-	deployment.Spec.Template.Spec.Affinity.NodeAffinity = nodeAffinity
-
+	podSpec.Affinity.NodeAffinity = nodeAffinity
 	return nil
 }
 
-func (t *affinityTrait) addPodAffinity(e *Environment, deployment *appsv1.Deployment) error {
+func (t *affinityTrait) addPodAffinity(e *Environment, podSpec *corev1.PodSpec) error {
 	if util.IsNilOrFalse(t.PodAffinity) && len(t.PodAffinityLabels) == 0 {
 		return nil
 	}
@@ -185,16 +178,11 @@ func (t *affinityTrait) addPodAffinity(e *Environment, deployment *appsv1.Deploy
 		},
 	}
 
-	if deployment.Spec.Template.Spec.Affinity == nil {
-		deployment.Spec.Template.Spec.Affinity = &corev1.Affinity{}
-	}
-
-	deployment.Spec.Template.Spec.Affinity.PodAffinity = podAffinity
-
+	podSpec.Affinity.PodAffinity = podAffinity
 	return nil
 }
 
-func (t *affinityTrait) addPodAntiAffinity(e *Environment, deployment *appsv1.Deployment) error {
+func (t *affinityTrait) addPodAntiAffinity(e *Environment, podSpec *corev1.PodSpec) error {
 	if util.IsNilOrFalse(t.PodAntiAffinity) && len(t.PodAntiAffinityLabels) == 0 {
 		return nil
 	}
@@ -241,12 +229,7 @@ func (t *affinityTrait) addPodAntiAffinity(e *Environment, deployment *appsv1.De
 		},
 	}
 
-	if deployment.Spec.Template.Spec.Affinity == nil {
-		deployment.Spec.Template.Spec.Affinity = &corev1.Affinity{}
-	}
-
-	deployment.Spec.Template.Spec.Affinity.PodAntiAffinity = podAntiAffinity
-
+	podSpec.Affinity.PodAntiAffinity = podAntiAffinity
 	return nil
 }
 
diff --git a/pkg/trait/affinity_test.go b/pkg/trait/affinity_test.go
index f74bc60..b008b6a 100644
--- a/pkg/trait/affinity_test.go
+++ b/pkg/trait/affinity_test.go
@@ -22,17 +22,16 @@ import (
 
 	"github.com/stretchr/testify/assert"
 
-	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/util"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
 )
 
 func TestConfigureAffinityTraitDoesSucceed(t *testing.T) {
-	affinityTrait, environment, _ := createNominalAffinityTest()
+	affinityTrait := createNominalAffinityTest()
+	environment, _ := createNominalDeploymentTraitTest()
 	configured, err := affinityTrait.Configure(environment)
 
 	assert.True(t, configured)
@@ -40,7 +39,8 @@ func TestConfigureAffinityTraitDoesSucceed(t *testing.T) {
 }
 
 func TestConfigureAffinityTraitWithConflictingAffinitiesFails(t *testing.T) {
-	affinityTrait, environment, _ := createNominalAffinityTest()
+	affinityTrait := createNominalAffinityTest()
+	environment, _ := createNominalDeploymentTraitTest()
 	affinityTrait.PodAffinity = util.BoolP(true)
 	affinityTrait.PodAntiAffinity = util.BoolP(true)
 	configured, err := affinityTrait.Configure(environment)
@@ -50,8 +50,9 @@ func TestConfigureAffinityTraitWithConflictingAffinitiesFails(t *testing.T) {
 }
 
 func TestConfigureDisabledAffinityTraitFails(t *testing.T) {
-	affinityTrait, environment, _ := createNominalAffinityTest()
+	affinityTrait := createNominalAffinityTest()
 	affinityTrait.Enabled = new(bool)
+	environment, _ := createNominalDeploymentTraitTest()
 	configured, err := affinityTrait.Configure(environment)
 
 	assert.False(t, configured)
@@ -59,22 +60,45 @@ func TestConfigureDisabledAffinityTraitFails(t *testing.T) {
 }
 
 func TestApplyEmptyAffinityLabelsDoesSucceed(t *testing.T) {
-	affinityTrait, environment, _ := createNominalAffinityTest()
+	affinityTrait := createNominalAffinityTest()
 
-	err := affinityTrait.Apply(environment)
+	environment, deployment := createNominalDeploymentTraitTest()
+	testApplyEmptyAffinityLabelsDoesSucceed(t, affinityTrait, environment, deployment.Spec.Template.Spec.Affinity)
+
+	environment, knativeService := createNominalKnativeServiceTraitTest()
+	testApplyEmptyAffinityLabelsDoesSucceed(t, affinityTrait, environment, knativeService.Spec.Template.Spec.Affinity)
+
+	environment, cronJob := createNominalCronJobTraitTest()
+	testApplyEmptyAffinityLabelsDoesSucceed(t, affinityTrait, environment, cronJob.Spec.JobTemplate.Spec.Template.Spec.Affinity)
+}
+
+func testApplyEmptyAffinityLabelsDoesSucceed(t *testing.T, trait *affinityTrait, environment *Environment, affinity *corev1.Affinity) {
+	err := trait.Apply(environment)
 
 	assert.Nil(t, err)
+	assert.Nil(t, affinity)
 }
 
 func TestApplyNodeAffinityLabelsDoesSucceed(t *testing.T) {
-	affinityTrait, environment, deployment := createNominalAffinityTest()
+	affinityTrait := createNominalAffinityTest()
 	affinityTrait.NodeAffinityLabels = []string{"criteria = value"}
 
-	err := affinityTrait.Apply(environment)
+	environment, deployment := createNominalDeploymentTraitTest()
+	testApplyNodeAffinityLabelsDoesSucceed(t, affinityTrait, environment, &deployment.Spec.Template.Spec)
+
+	environment, knativeService := createNominalKnativeServiceTraitTest()
+	testApplyNodeAffinityLabelsDoesSucceed(t, affinityTrait, environment, &knativeService.Spec.Template.Spec.PodSpec)
+
+	environment, cronJob := createNominalCronJobTraitTest()
+	testApplyNodeAffinityLabelsDoesSucceed(t, affinityTrait, environment, &cronJob.Spec.JobTemplate.Spec.Template.Spec)
+}
+
+func testApplyNodeAffinityLabelsDoesSucceed(t *testing.T, trait *affinityTrait, environment *Environment, podSpec *corev1.PodSpec) {
+	err := trait.Apply(environment)
 
 	assert.Nil(t, err)
-	assert.NotNil(t, deployment.Spec.Template.Spec.Affinity.NodeAffinity)
-	nodeAffinity := deployment.Spec.Template.Spec.Affinity.NodeAffinity
+	assert.NotNil(t, podSpec.Affinity.NodeAffinity)
+	nodeAffinity := podSpec.Affinity.NodeAffinity
 	assert.NotNil(t, nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0])
 	nodeSelectorRequirement := nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0]
 	assert.Equal(t, "criteria", nodeSelectorRequirement.Key)
@@ -83,15 +107,26 @@ func TestApplyNodeAffinityLabelsDoesSucceed(t *testing.T) {
 }
 
 func TestApplyPodAntiAffinityLabelsDoesSucceed(t *testing.T) {
-	affinityTrait, environment, deployment := createNominalAffinityTest()
+	affinityTrait := createNominalAffinityTest()
 	affinityTrait.PodAntiAffinity = util.BoolP(true)
 	affinityTrait.PodAntiAffinityLabels = []string{"criteria != value"}
 
-	err := affinityTrait.Apply(environment)
+	environment, deployment := createNominalDeploymentTraitTest()
+	testApplyPodAntiAffinityLabelsDoesSucceed(t, affinityTrait, environment, &deployment.Spec.Template.Spec)
+
+	environment, knativeService := createNominalKnativeServiceTraitTest()
+	testApplyPodAntiAffinityLabelsDoesSucceed(t, affinityTrait, environment, &knativeService.Spec.Template.Spec.PodSpec)
+
+	environment, cronJob := createNominalCronJobTraitTest()
+	testApplyPodAntiAffinityLabelsDoesSucceed(t, affinityTrait, environment, &cronJob.Spec.JobTemplate.Spec.Template.Spec)
+}
+
+func testApplyPodAntiAffinityLabelsDoesSucceed(t *testing.T, trait *affinityTrait, environment *Environment, podSpec *corev1.PodSpec) {
+	err := trait.Apply(environment)
 
 	assert.Nil(t, err)
-	assert.NotNil(t, deployment.Spec.Template.Spec.Affinity.PodAntiAffinity)
-	podAntiAffinity := deployment.Spec.Template.Spec.Affinity.PodAntiAffinity
+	assert.NotNil(t, podSpec.Affinity.PodAntiAffinity)
+	podAntiAffinity := podSpec.Affinity.PodAntiAffinity
 	assert.NotNil(t, podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].LabelSelector.MatchExpressions[0])
 	userRequirement := podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].LabelSelector.MatchExpressions[0]
 	assert.Equal(t, "criteria", userRequirement.Key)
@@ -105,15 +140,26 @@ func TestApplyPodAntiAffinityLabelsDoesSucceed(t *testing.T) {
 }
 
 func TestApplyPodAffinityLabelsDoesSucceed(t *testing.T) {
-	affinityTrait, environment, deployment := createNominalAffinityTest()
+	affinityTrait := createNominalAffinityTest()
 	affinityTrait.PodAffinity = util.BoolP(true)
 	affinityTrait.PodAffinityLabels = []string{"!criteria"}
 
-	err := affinityTrait.Apply(environment)
+	environment, deployment := createNominalDeploymentTraitTest()
+	testApplyPodAffinityLabelsDoesSucceed(t, affinityTrait, environment, &deployment.Spec.Template.Spec)
+
+	environment, knativeService := createNominalKnativeServiceTraitTest()
+	testApplyPodAffinityLabelsDoesSucceed(t, affinityTrait, environment, &knativeService.Spec.Template.Spec.PodSpec)
+
+	environment, cronJob := createNominalCronJobTraitTest()
+	testApplyPodAffinityLabelsDoesSucceed(t, affinityTrait, environment, &cronJob.Spec.JobTemplate.Spec.Template.Spec)
+}
+
+func testApplyPodAffinityLabelsDoesSucceed(t *testing.T, trait *affinityTrait, environment *Environment, podSpec *corev1.PodSpec) {
+	err := trait.Apply(environment)
 
 	assert.Nil(t, err)
-	assert.NotNil(t, deployment.Spec.Template.Spec.Affinity.PodAffinity)
-	podAffinity := deployment.Spec.Template.Spec.Affinity.PodAffinity
+	assert.NotNil(t, podSpec.Affinity.PodAffinity)
+	podAffinity := podSpec.Affinity.PodAffinity
 	assert.NotNil(t, podAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].LabelSelector.MatchExpressions[0])
 	userRequirement := podAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].LabelSelector.MatchExpressions[0]
 	assert.Equal(t, "criteria", userRequirement.Key)
@@ -125,31 +171,10 @@ func TestApplyPodAffinityLabelsDoesSucceed(t *testing.T) {
 	assert.ElementsMatch(t, [1]string{"integration-name"}, integrationRequirement.Values)
 }
 
-func createNominalAffinityTest() (*affinityTrait, *Environment, *appsv1.Deployment) {
+func createNominalAffinityTest() *affinityTrait {
 	trait := newAffinityTrait().(*affinityTrait)
 	enabled := true
 	trait.Enabled = &enabled
 
-	deployment := &appsv1.Deployment{
-		ObjectMeta: metav1.ObjectMeta{
-			Name: "integration-name",
-		},
-		Spec: appsv1.DeploymentSpec{
-			Template: corev1.PodTemplateSpec{},
-		},
-	}
-
-	environment := &Environment{
-		Integration: &v1.Integration{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: "integration-name",
-			},
-			Status: v1.IntegrationStatus{
-				Phase: v1.IntegrationPhaseDeploying,
-			},
-		},
-		Resources: kubernetes.NewCollection(deployment),
-	}
-
-	return trait, environment, deployment
+	return trait
 }