diff --git a/pkg/controller/deployment/deployment_controller.go b/pkg/controller/deployment/deployment_controller.go index e6e2c2db1..807bffa7b 100644 --- a/pkg/controller/deployment/deployment_controller.go +++ b/pkg/controller/deployment/deployment_controller.go @@ -106,6 +106,11 @@ func (r *ReconcileDeployment) Reconcile(request reconcile.Request) (reconcile.Re return reconcile.Result{}, tracing.HandleError(err, span) } + if dep.Labels["app"] == "jaeger" { + // Don't touch jaeger deployments + return reconcile.Result{}, nil + } + ns := &corev1.Namespace{} err = r.rClient.Get(ctx, types.NamespacedName{Name: request.Namespace}, ns) // we shouldn't fail if the namespace object can't be obtained diff --git a/pkg/controller/deployment/deployment_controller_test.go b/pkg/controller/deployment/deployment_controller_test.go index 11bd1e0f0..67511f04e 100644 --- a/pkg/controller/deployment/deployment_controller_test.go +++ b/pkg/controller/deployment/deployment_controller_test.go @@ -205,3 +205,104 @@ func TestReconcileConfigMaps(t *testing.T) { }) } } + +func TestReconcilieDeployment(t *testing.T) { + namespacedName := types.NamespacedName{ + Name: "jaeger-query", + Namespace: "my-ns", + } + + jaeger := v1.NewJaeger(types.NamespacedName{ + Namespace: "observability", + Name: "my-instance", + }) + + s := scheme.Scheme + s.AddKnownTypes(v1.SchemeGroupVersion, jaeger) + s.AddKnownTypes(v1.SchemeGroupVersion, &v1.JaegerList{}) + + testCases := []struct { + desc string + dep *appsv1.Deployment + expectedContiners int + }{ + { + desc: "Should not remove the instance from a jaeger component", + dep: inject.Sidecar(jaeger, &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Annotations: map[string]string{}, + Labels: map[string]string{ + "app": "jaeger", + }, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "only_container", + }}, + }, + }, + }, + }), + expectedContiners: 2, + }, + { + desc: "Should remove the instance", + dep: inject.Sidecar(jaeger, &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Name, + Namespace: namespacedName.Namespace, + Annotations: map[string]string{}, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "only_container", + }}, + }, + }, + }, + }), + expectedContiners: 1, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + + assert.Equal(t, 2, len(tc.dep.Spec.Template.Spec.Containers)) + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespacedName.Namespace, + }, + } + + cl := fake.NewFakeClient(tc.dep, ns) + r := &ReconcileDeployment{ + client: cl, + rClient: cl, + scheme: s, + } + req := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: tc.dep.Name, + Namespace: tc.dep.Namespace, + }, + } + + _, err := r.Reconcile(req) + persisted := &appsv1.Deployment{} + cl.Get(context.Background(), req.NamespacedName, persisted) + + assert.Equal(t, tc.expectedContiners, len(persisted.Spec.Template.Spec.Containers)) + + require.NoError(t, err) + }) + } +} diff --git a/pkg/controller/namespace/namespace_controller.go b/pkg/controller/namespace/namespace_controller.go index 5ed52b9e1..93d5f2192 100644 --- a/pkg/controller/namespace/namespace_controller.go +++ b/pkg/controller/namespace/namespace_controller.go @@ -124,6 +124,11 @@ func (r *ReconcileNamespace) Reconcile(request reconcile.Request) (reconcile.Res for i := 0; i < len(deps.Items); i++ { dep := &deps.Items[i] + if dep.Labels["app"] == "jaeger" { + // Don't touch jaeger deployments + continue + } + if inject.Needed(dep, ns) { jaegers := &v1.JaegerList{} opts := []client.ListOption{} diff --git a/pkg/controller/namespace/namespace_controller_test.go b/pkg/controller/namespace/namespace_controller_test.go new file mode 100644 index 000000000..ce93b1588 --- /dev/null +++ b/pkg/controller/namespace/namespace_controller_test.go @@ -0,0 +1,119 @@ +package namespace + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "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/reconcile" + + v1 "github.com/jaegertracing/jaeger-operator/pkg/apis/jaegertracing/v1" + "github.com/jaegertracing/jaeger-operator/pkg/inject" +) + +func TestReconcilieDeployment(t *testing.T) { + depNamespacedName := types.NamespacedName{ + Name: "jaeger-query", + Namespace: "my-ns", + } + + jaeger := v1.NewJaeger(types.NamespacedName{ + Namespace: "observability", + Name: "my-instance", + }) + + s := scheme.Scheme + s.AddKnownTypes(v1.SchemeGroupVersion, jaeger) + s.AddKnownTypes(v1.SchemeGroupVersion, &v1.JaegerList{}) + + testCases := []struct { + desc string + dep *appsv1.Deployment + expectedContiners int + }{ + { + desc: "Should not remove the instance from a jaeger component", + dep: inject.Sidecar(jaeger, &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: depNamespacedName.Name, + Namespace: depNamespacedName.Namespace, + Annotations: map[string]string{}, + Labels: map[string]string{ + "app": "jaeger", + }, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "only_container", + }}, + }, + }, + }, + }), + expectedContiners: 2, + }, + { + desc: "Should remove the instance", + dep: inject.Sidecar(jaeger, &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: depNamespacedName.Name, + Namespace: depNamespacedName.Namespace, + Annotations: map[string]string{}, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "only_container", + }}, + }, + }, + }, + }), + expectedContiners: 1, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + + assert.Equal(t, 2, len(tc.dep.Spec.Template.Spec.Containers)) + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: depNamespacedName.Namespace, + }, + } + + cl := fake.NewFakeClient(tc.dep, ns) + r := &ReconcileNamespace{ + client: cl, + rClient: cl, + scheme: s, + } + req := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: depNamespacedName.Namespace, + }, + } + + _, err := r.Reconcile(req) + persisted := &appsv1.Deployment{} + cl.Get(context.Background(), depNamespacedName, persisted) + + assert.Equal(t, tc.expectedContiners, len(persisted.Spec.Template.Spec.Containers)) + + require.NoError(t, err) + }) + } +}