Skip to content

Commit

Permalink
Trigger deployments reconciliation when jaeger instance is created (#…
Browse files Browse the repository at this point in the history
…1334)

* Trigger deployment reconciliation when jaeger instance is created

Signed-off-by: Ruben Vargas Palma <ruben.vp8510@gmail.com>

* Refactor reconciliation request fanout and add tests

Signed-off-by: Juraci Paixão Kröhling <juraci@kroehling.de>

* Added annotation to test some-other-jaeger instance

Signed-off-by: Ruben Vargas Palma <ruben.vp8510@gmail.com>

Co-authored-by: Juraci Paixão Kröhling <juraci@kroehling.de>
  • Loading branch information
rubenvp8510 and jpkrohling authored Dec 9, 2020
1 parent 55cb24a commit e48622a
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 1 deletion.
55 changes: 54 additions & 1 deletion pkg/controller/deployment/deployment_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
return err
}

return nil
return c.Watch(&source.Kind{Type: &v1.Jaeger{}}, &handler.EnqueueRequestsFromMapFunc{
ToRequests: handler.ToRequestsFunc(r.(*ReconcileDeployment).syncOnJaegerChanges),
})
}

var _ reconcile.Reconciler = &ReconcileDeployment{}
Expand Down Expand Up @@ -178,3 +180,54 @@ func (r *ReconcileDeployment) Reconcile(request reconcile.Request) (reconcile.Re

return reconcile.Result{}, nil
}

func (r *ReconcileDeployment) syncOnJaegerChanges(event handler.MapObject) []reconcile.Request {
reconciliations := []reconcile.Request{}
nss := map[string]corev1.Namespace{} // namespace cache

jaeger, ok := event.Object.(*v1.Jaeger)
if !ok {
return reconciliations
}

deployments := appsv1.DeploymentList{}
err := r.client.List(context.Background(), &deployments)
if err != nil {
return reconciliations
}

for _, dep := range deployments.Items {
nsn := types.NamespacedName{Name: dep.Name, Namespace: dep.Namespace}
req := reconcile.Request{NamespacedName: nsn}

// if there's an assigned instance to this deployment, and it's not the one that triggered the current event,
// we don't need to trigger a reconciliation for it
if val, ok := dep.Labels[inject.Label]; ok && val != jaeger.Name {
continue
}

// if the deployment has the sidecar annotation, trigger a reconciliation
if _, ok := dep.Annotations[inject.Annotation]; ok {
reconciliations = append(reconciliations, req)
continue
}

// if we don't have the namespace in the cache yet, retrieve it
var ns corev1.Namespace
if ns, ok = nss[dep.Namespace]; !ok {
err := r.client.Get(context.Background(), types.NamespacedName{Name: dep.Namespace}, &ns)
if err != nil {
continue
}
nss[ns.Name] = ns
}

// if the namespace has the sidecar annotation, trigger a reconciliation
if _, ok := ns.Annotations[inject.Annotation]; ok {
reconciliations = append(reconciliations, req)
continue
}

}
return reconciliations
}
136 changes: 136 additions & 0 deletions pkg/controller/deployment/deployment_controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package deployment

import (
"sort"
"testing"

v1 "github.com/jaegertracing/jaeger-operator/pkg/apis/jaegertracing/v1"
"github.com/jaegertracing/jaeger-operator/pkg/inject"
"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"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

func TestSyncOnJaegerChanges(t *testing.T) {
// prepare
jaeger := v1.NewJaeger(types.NamespacedName{
Namespace: "observability",
Name: "my-instance",
})

objs := []runtime.Object{
&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{
Name: "ns-with-annotation",
Annotations: map[string]string{
inject.Annotation: "true",
},
}},
&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "dep-without-annotation",
Namespace: "ns-with-annotation",
},
},
&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "dep-with-annotation",
Namespace: "ns-with-annotation",
Annotations: map[string]string{
inject.Annotation: "true",
},
},
},

&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{
Name: "ns-without-annotation",
}},
&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "dep-without-annotation",
Namespace: "ns-without-annotation",
},
},
&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "dep-with-annotation",
Namespace: "ns-without-annotation",
Annotations: map[string]string{
inject.Annotation: "true",
},
},
},
&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "dep-with-another-jaegers-label",
Namespace: "ns-without-annotation",
Annotations: map[string]string{
inject.Annotation: "true",
},
Labels: map[string]string{
inject.Label: "some-other-jaeger",
},
},
},
&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "dep-affected-jaeger-label",
Namespace: "ns-without-annotation",
Annotations: map[string]string{
inject.Annotation: "true",
},
Labels: map[string]string{
inject.Label: jaeger.Name,
},
},
},
}

s := scheme.Scheme
cl := fake.NewFakeClient(objs...)
r := &ReconcileDeployment{
client: cl,
rClient: cl,
scheme: s,
}

// test
requests := r.syncOnJaegerChanges(handler.MapObject{
Meta: &jaeger.ObjectMeta,
Object: jaeger,
})

// verify
assert.Len(t, requests, 4)

expected := []reconcile.Request{
{NamespacedName: types.NamespacedName{
Name: "dep-without-annotation",
Namespace: "ns-with-annotation",
}},
{NamespacedName: types.NamespacedName{
Name: "dep-with-annotation",
Namespace: "ns-with-annotation",
}},
{NamespacedName: types.NamespacedName{
Name: "dep-with-annotation",
Namespace: "ns-without-annotation",
}},
{NamespacedName: types.NamespacedName{
Name: "dep-affected-jaeger-label",
Namespace: "ns-without-annotation",
}},
}

sort.Slice(requests, func(i, j int) bool {
return requests[i].Namespace < requests[j].Namespace && requests[i].Name < requests[j].Name
})

assert.Equal(t, expected, requests)
}

0 comments on commit e48622a

Please sign in to comment.