You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2019/03/08 09:10:51 UTC

[camel-k] branch master updated: fix(owner): ensure lebsl/annotations are propagated to child resources

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 82c1a87  fix(owner): ensure lebsl/annotations are propagated to child resources
82c1a87 is described below

commit 82c1a87f23ef035b44db28d4617301289f1e3a12
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Thu Mar 7 06:53:53 2019 +0100

    fix(owner): ensure lebsl/annotations are propagated to child resources
---
 pkg/trait/owner.go      | 123 +++++++++++++++++++++++++++++-------------------
 pkg/trait/owner_test.go |  78 ++++++++++++++++++++++++++++--
 2 files changed, 150 insertions(+), 51 deletions(-)

diff --git a/pkg/trait/owner.go b/pkg/trait/owner.go
index 4dd2a2e..5297e7d 100644
--- a/pkg/trait/owner.go
+++ b/pkg/trait/owner.go
@@ -20,10 +20,13 @@ package trait
 import (
 	"strings"
 
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/util/finalizer"
+
 	"github.com/pkg/errors"
 
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
+	appsv1 "k8s.io/api/apps/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -51,19 +54,6 @@ func (t *ownerTrait) Configure(e *Environment) (bool, error) {
 		return false, nil
 	}
 
-	ok, err := finalizer.Exists(e.Integration, finalizer.CamelIntegrationFinalizer)
-	if err != nil {
-		return false, errors.Wrap(err, "failed to read finalizer"+finalizer.CamelIntegrationFinalizer)
-	}
-
-	if ok {
-		//
-		// do not enable this trait if the integration has
-		// a finalizer
-		//
-		return false, nil
-	}
-
 	return e.IntegrationInPhase(v1alpha1.IntegrationPhaseDeploying), nil
 }
 
@@ -71,51 +61,88 @@ func (t *ownerTrait) Apply(e *Environment) error {
 	controller := true
 	blockOwnerDeletion := true
 
-	targetLabels := map[string]string{}
-	for _, k := range strings.Split(t.TargetLabels, ",") {
-		if v, ok := e.Integration.Labels[k]; ok {
-			targetLabels[k] = v
+	targetLabels := make(map[string]string)
+	if e.Integration.Labels != nil {
+		for _, k := range strings.Split(t.TargetLabels, ",") {
+			if v, ok := e.Integration.Labels[k]; ok {
+				targetLabels[k] = v
+			}
 		}
 	}
 
-	targetAnnotations := map[string]string{}
-	for _, k := range strings.Split(t.TargetAnnotations, ",") {
-		if v, ok := e.Integration.Annotations[k]; ok {
-			targetAnnotations[k] = v
+	targetAnnotations := make(map[string]string)
+	if e.Integration.Annotations != nil {
+		for _, k := range strings.Split(t.TargetAnnotations, ",") {
+			if v, ok := e.Integration.Annotations[k]; ok {
+				targetAnnotations[k] = v
+			}
 		}
 	}
 
+	ok, err := finalizer.Exists(e.Integration, finalizer.CamelIntegrationFinalizer)
+	if err != nil {
+		return errors.Wrap(err, "failed to read finalizer"+finalizer.CamelIntegrationFinalizer)
+	}
+
 	e.Resources.VisitMetaObject(func(res metav1.Object) {
-		// Add owner reference
-		references := []metav1.OwnerReference{
-			{
-				APIVersion:         e.Integration.APIVersion,
-				Kind:               e.Integration.Kind,
-				Name:               e.Integration.Name,
-				UID:                e.Integration.UID,
-				Controller:         &controller,
-				BlockOwnerDeletion: &blockOwnerDeletion,
-			},
+		//
+		// do not add owner reference if the finalizer is set
+		// so resources are not automatically deleted by k8s
+		// when owner is deleted
+		//
+		if !ok {
+			references := []metav1.OwnerReference{
+				{
+					APIVersion:         e.Integration.APIVersion,
+					Kind:               e.Integration.Kind,
+					Name:               e.Integration.Name,
+					UID:                e.Integration.UID,
+					Controller:         &controller,
+					BlockOwnerDeletion: &blockOwnerDeletion,
+				},
+			}
+			res.SetOwnerReferences(references)
 		}
-		res.SetOwnerReferences(references)
 
 		// Transfer annotations
-		annotations := res.GetAnnotations()
-		for k, v := range targetAnnotations {
-			if _, ok := annotations[k]; !ok {
-				annotations[k] = v
-			}
-		}
-		res.SetAnnotations(annotations)
+		t.propagateLabelAndAnnotations(res, targetLabels, targetAnnotations)
+	})
 
-		// Transfer labels
-		labels := res.GetLabels()
-		for k, v := range targetLabels {
-			if _, ok := labels[k]; !ok {
-				labels[k] = v
-			}
-		}
-		res.SetLabels(labels)
+	e.Resources.VisitDeployment(func(deployment *appsv1.Deployment) {
+		t.propagateLabelAndAnnotations(&deployment.Spec.Template, targetLabels, targetAnnotations)
+	})
+
+	e.Resources.VisitKnativeService(func(service *serving.Service) {
+		t.propagateLabelAndAnnotations(&service.Spec.RunLatest.Configuration.RevisionTemplate, targetLabels, targetAnnotations)
 	})
+
 	return nil
 }
+
+func (t *ownerTrait) propagateLabelAndAnnotations(res metav1.Object, targetLabels map[string]string, targetAnnotations map[string]string) {
+	// Transfer annotations
+	annotations := res.GetAnnotations()
+	if annotations == nil {
+		annotations = make(map[string]string)
+	}
+
+	for k, v := range targetAnnotations {
+		if _, ok := annotations[k]; !ok {
+			annotations[k] = v
+		}
+	}
+	res.SetAnnotations(annotations)
+
+	// Transfer labels
+	labels := res.GetLabels()
+	if labels == nil {
+		labels = make(map[string]string)
+	}
+
+	for k, v := range targetLabels {
+		if _, ok := labels[k]; !ok {
+			labels[k] = v
+		}
+	}
+	res.SetLabels(labels)
+}
diff --git a/pkg/trait/owner_test.go b/pkg/trait/owner_test.go
index 27d0f47..2c08f0e 100644
--- a/pkg/trait/owner_test.go
+++ b/pkg/trait/owner_test.go
@@ -20,18 +20,90 @@ package trait
 import (
 	"testing"
 
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/util/finalizer"
 
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/stretchr/testify/assert"
+
+	appsv1 "k8s.io/api/apps/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 func TestOwnerWithFinalizer(t *testing.T) {
-	env := createTestEnv(t, v1alpha1.IntegrationPlatformClusterOpenShift, "camel:core")
+	env := SetUpOwnerEnvironment(t)
 	env.Integration.Finalizers = []string{finalizer.CamelIntegrationFinalizer}
 
 	processTestEnv(t, env)
 
 	assert.NotEmpty(t, env.ExecutedTraits)
-	assert.Nil(t, env.GetTrait(ID("owner")))
+	assert.NotNil(t, env.GetTrait(ID("owner")))
+
+	ValidateOwnerResources(t, env, false)
+}
+
+func TestOwnerWithoutFinalizer(t *testing.T) {
+	env := SetUpOwnerEnvironment(t)
+
+	processTestEnv(t, env)
+
+	assert.NotEmpty(t, env.ExecutedTraits)
+	assert.NotNil(t, env.GetTrait(ID("owner")))
+
+	ValidateOwnerResources(t, env, true)
+}
+
+func SetUpOwnerEnvironment(t *testing.T) *Environment {
+	env := createTestEnv(t, v1alpha1.IntegrationPlatformClusterOpenShift, "camel:core")
+	env.Integration.Spec.Traits = map[string]v1alpha1.IntegrationTraitSpec{
+		"owner": {
+			Configuration: map[string]string{
+				"target-labels":      "com.mycompany/mylabel1",
+				"target-annotations": "com.mycompany/myannotation2",
+			},
+		},
+	}
+
+	env.Integration.SetLabels(map[string]string{
+		"com.mycompany/mylabel1": "myvalue1",
+		"com.mycompany/mylabel2": "myvalue2",
+		"org.apache.camel/l1":    "l1",
+	})
+	env.Integration.SetAnnotations(map[string]string{
+		"com.mycompany/myannotation1": "myannotation1",
+		"com.mycompany/myannotation2": "myannotation2",
+	})
+
+	return env
+}
+
+func ValidateOwnerResources(t *testing.T, env *Environment, withOwnerRef bool) {
+	assert.NotEmpty(t, env.Resources.Items())
+
+	env.Resources.VisitMetaObject(func(res metav1.Object) {
+		if withOwnerRef {
+			assert.NotEmpty(t, res.GetOwnerReferences())
+		} else {
+			assert.Empty(t, res.GetOwnerReferences())
+		}
+
+		ValidateLabelsAndAnnotations(t, res)
+	})
+
+	deployments := make([]*appsv1.Deployment, 0)
+	env.Resources.VisitDeployment(func(deployment *appsv1.Deployment) {
+		deployments = append(deployments, deployment)
+	})
+
+	assert.Len(t, deployments, 1)
+	ValidateLabelsAndAnnotations(t, &deployments[0].Spec.Template)
+}
+
+func ValidateLabelsAndAnnotations(t *testing.T, res metav1.Object) {
+	assert.Contains(t, res.GetLabels(), "com.mycompany/mylabel1")
+	assert.Equal(t, "myvalue1", res.GetLabels()["com.mycompany/mylabel1"])
+
+	assert.NotContains(t, res.GetLabels(), "com.mycompany/mylabel2")
+
+	assert.Contains(t, res.GetAnnotations(), "com.mycompany/myannotation2")
+	assert.Equal(t, "myannotation2", res.GetAnnotations()["com.mycompany/myannotation2"])
 }