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 <lburgazz...@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"])
 }

Reply via email to