Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate odigos-instrumentation label to Source CRD #2231

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
94497dc
k8sutils: add Source helpers and remove unused label helpers
damemi Jan 14, 2025
d2e286a
api+webhook: fix namespace checks
damemi Jan 14, 2025
adacba0
startlangdetection: add label->source enable migration
damemi Jan 14, 2025
08f1eb9
deleteinstrumentationconfig: add label->source disabled migration
damemi Jan 14, 2025
e79e251
Update tests
damemi Jan 14, 2025
7fd632b
startlangdetection: update WorkloadEnabledPredicate->WorkloadAvailabl…
damemi Jan 14, 2025
801f5fa
Update controller predicates and IsObjectInstrumentedBySource check
damemi Jan 14, 2025
929455e
lint: Add WorkloadKindNamespace const and other linters
damemi Jan 15, 2025
804b47a
Build Source webhooks in 1 call
damemi Jan 15, 2025
47dcd81
Use K8SUpdateErrorHandler in functions that update Source + use Calcu…
damemi Jan 15, 2025
773dc66
Remove redundant Source checks for controllers using predicates
damemi Jan 15, 2025
8a96dd9
Fix IsObjectInstrumentedBySource check
damemi Jan 15, 2025
2292067
deleteinstrumentationconfig: Use IsObjectInstrumentedBySource in checks
damemi Jan 15, 2025
bff839f
feedback: Rename Source Predicates, rename IsActiveSource->IsSourceRe…
damemi Jan 16, 2025
8f469cf
Merge branch 'main' into source-label-migration
damemi Jan 16, 2025
8da249a
Merge branch 'main' into source-label-migration
damemi Jan 16, 2025
bb3201e
Merge branch 'main' into source-label-migration
damemi Jan 16, 2025
c1ee54d
Merge branch 'main' into source-label-migration
damemi Jan 17, 2025
ff9466c
Don't let NotFound errors keep you from deleting the finalizer
damemi Jan 17, 2025
cc31bbe
Add instrumentation filter in workload predicate for startlangdetection
damemi Jan 17, 2025
7406790
Merge branch 'main' into source-label-migration
damemi Jan 17, 2025
e1291f0
Fix make-dev-tests (#2235)
damemi Jan 17, 2025
0aa9632
Pass events with errors in workload predicate
damemi Jan 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ crd-apply: api-all cli-upgrade
dev-tests-kind-cluster:
@echo "Creating a kind cluster for development"
kind delete cluster
kind create cluster
kind create cluster --config=tests/common/apply/kind-config.yaml

.PHONY: dev-tests-setup
dev-tests-setup: TAG := e2e-test
Expand Down
19 changes: 12 additions & 7 deletions api/odigos/v1alpha1/source_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,19 @@ func GetSources(ctx context.Context, kubeClient client.Client, obj client.Object
var err error
workloadSources := &WorkloadSources{}

if obj.GetObjectKind().GroupVersionKind().Kind != "Namespace" {
namespace := obj.GetNamespace()
if len(namespace) == 0 && obj.GetObjectKind().GroupVersionKind().Kind == string(workload.WorkloadKindNamespace) {
RonFed marked this conversation as resolved.
Show resolved Hide resolved
namespace = obj.GetName()
}

if obj.GetObjectKind().GroupVersionKind().Kind != string(workload.WorkloadKindNamespace) {
sourceList := SourceList{}
selector := labels.SelectorFromSet(labels.Set{
consts.WorkloadNameLabel: obj.GetName(),
consts.WorkloadNamespaceLabel: obj.GetNamespace(),
consts.WorkloadNamespaceLabel: namespace,
consts.WorkloadKindLabel: obj.GetObjectKind().GroupVersionKind().Kind,
})
err := kubeClient.List(ctx, &sourceList, &client.ListOptions{LabelSelector: selector}, client.InNamespace(obj.GetNamespace()))
err := kubeClient.List(ctx, &sourceList, &client.ListOptions{LabelSelector: selector}, client.InNamespace(namespace))
if err != nil {
return nil, err
}
Expand All @@ -108,11 +113,11 @@ func GetSources(ctx context.Context, kubeClient client.Client, obj client.Object

namespaceSourceList := SourceList{}
namespaceSelector := labels.SelectorFromSet(labels.Set{
consts.WorkloadNameLabel: obj.GetNamespace(),
consts.WorkloadNamespaceLabel: obj.GetNamespace(),
consts.WorkloadKindLabel: "Namespace",
consts.WorkloadNameLabel: namespace,
consts.WorkloadNamespaceLabel: namespace,
consts.WorkloadKindLabel: string(workload.WorkloadKindNamespace),
})
err = kubeClient.List(ctx, &namespaceSourceList, &client.ListOptions{LabelSelector: namespaceSelector}, client.InNamespace(obj.GetNamespace()))
err = kubeClient.List(ctx, &namespaceSourceList, &client.ListOptions{LabelSelector: namespaceSelector}, client.InNamespace(namespace))
if err != nil {
return nil, err
}
Expand Down
57 changes: 0 additions & 57 deletions helm/odigos/templates/instrumentor/webhook-pod.yaml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,42 @@
{{- $cert := genSignedCert "serving-cert" nil $altNames 365 $ca -}}
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: mutating-webhook-configuration
labels:
app.kubernetes.io/name: pod-mutating-webhook
app.kubernetes.io/instance: mutating-webhook-configuration
app.kubernetes.io/component: webhook
app.kubernetes.io/created-by: instrumentor
app.kubernetes.io/part-of: odigos
webhooks:
- name: pod-mutating-webhook.odigos.io
clientConfig:
caBundle: {{ $ca.Cert | b64enc }}
service:
name: odigos-instrumentor
namespace: {{ .Release.Namespace }}
path: /mutate--v1-pod
port: 9443
rules:
- operations:
- CREATE
- UPDATE
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
scope: Namespaced
failurePolicy: Ignore
reinvocationPolicy: IfNeeded
sideEffects: None
objectSelector:
matchLabels:
odigos.io/inject-instrumentation: "true"
timeoutSeconds: 10
admissionReviewVersions: ["v1"]
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: source-mutating-webhook-configuration
labels:
Expand Down Expand Up @@ -64,4 +100,23 @@ webhooks:
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 10
admissionReviewVersions: ["v1"]
admissionReviewVersions: ["v1"]
---
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
name: webhook-cert
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: instrumentor-cert
app.kubernetes.io/instance: instrumentor-cert
app.kubernetes.io/component: certificate
app.kubernetes.io/created-by: instrumentor
app.kubernetes.io/part-of: odigos
annotations:
"helm.sh/hook": "pre-install,pre-upgrade"
"helm.sh/hook-delete-policy": "before-hook-creation"
data:
tls.crt: {{ $cert.Cert | b64enc }}
tls.key: {{ $cert.Key | b64enc }}
24 changes: 9 additions & 15 deletions instrumentor/controllers/deleteinstrumentationconfig/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,29 @@ package deleteinstrumentationconfig
import (
"context"

odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1"
"github.com/odigos-io/odigos/common/consts"
"github.com/odigos-io/odigos/k8sutils/pkg/workload"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"

odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1"
"github.com/odigos-io/odigos/common/consts"
sourceutils "github.com/odigos-io/odigos/k8sutils/pkg/source"
"github.com/odigos-io/odigos/k8sutils/pkg/workload"
)

func reconcileWorkloadObject(ctx context.Context, kubeClient client.Client, workloadObject client.Object) error {
logger := log.FromContext(ctx)
instEffectiveEnabled, err := workload.IsWorkloadInstrumentationEffectiveEnabled(ctx, kubeClient, workloadObject)
if err != nil {
logger.Error(err, "error checking if instrumentation is effective")
return err
}

if instEffectiveEnabled {
return nil
if err := sourceutils.MigrateInstrumentationLabelToDisabledSource(ctx, kubeClient, workloadObject, workload.WorkloadKindFromClientObject(workloadObject)); err != nil {
return err
}

// Check if a Source object exists for this workload
sourceList, err := odigosv1.GetSources(ctx, kubeClient, workloadObject)
instrumented, err := sourceutils.IsObjectInstrumentedBySource(ctx, kubeClient, workloadObject)
if err != nil {
return err
}
if sourceList.Workload != nil || sourceList.Namespace != nil {
// Note that if a Source is being deleted, but still has the finalizer, it will still show up in this List
// So we can't use this check to trigger un-instrumentation via Source deletion
if instrumented {
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package deleteinstrumentationconfig
import (
"context"

k8sutils "github.com/odigos-io/odigos/k8sutils/pkg/utils"
apierrors "k8s.io/apimachinery/pkg/api/errors"

appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -48,5 +49,5 @@ func (r *DaemonSetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
}

err = reconcileWorkloadObject(ctx, r.Client, &ds)
return ctrl.Result{}, err
return k8sutils.K8SUpdateErrorHandler(err)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package deleteinstrumentationconfig
import (
"context"

k8sutils "github.com/odigos-io/odigos/k8sutils/pkg/utils"
appsv1 "k8s.io/api/apps/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -47,5 +48,5 @@ func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request)
}

err = reconcileWorkloadObject(ctx, r.Client, &dep)
return ctrl.Result{}, err
return k8sutils.K8SUpdateErrorHandler(err)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@ package deleteinstrumentationconfig_test

import (
"context"
"time"

odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1"
"github.com/odigos-io/odigos/instrumentor/internal/testutil"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

var _ = Describe("deleteInstrumentationConfig Deployment controller", func() {
ctx := context.Background()
var namespace *corev1.Namespace
var deployment *appsv1.Deployment
var source *odigosv1.Source
var instrumentationConfig *odigosv1.InstrumentationConfig

Describe("Delete InstrumentationConfig", func() {
Expand All @@ -28,14 +31,17 @@ var _ = Describe("deleteInstrumentationConfig Deployment controller", func() {
deployment = testutil.SetOdigosInstrumentationEnabled(testutil.NewMockTestDeployment(namespace))
Expect(k8sClient.Create(ctx, deployment)).Should(Succeed())

source = testutil.NewMockSource(deployment)
Expect(k8sClient.Create(ctx, source)).Should(Succeed())

instrumentationConfig = testutil.NewMockInstrumentationConfig(deployment)
Expect(k8sClient.Create(ctx, instrumentationConfig)).Should(Succeed())
})

It("InstrumentationConfig deleted after removing instrumentation label from deployment", func() {
It("InstrumentationConfig retained after removing instrumentation label from deployment", func() {
deployment = testutil.DeleteOdigosInstrumentationLabel(deployment)
Expect(k8sClient.Update(ctx, deployment)).Should(Succeed())
testutil.AssertInstrumentationConfigDeleted(ctx, k8sClient, instrumentationConfig)
testutil.AssertInstrumentationConfigRetained(ctx, k8sClient, instrumentationConfig)
})

It("InstrumentationConfig deleted after setting instrumentation label to disabled", func() {
Expand All @@ -52,9 +58,15 @@ var _ = Describe("deleteInstrumentationConfig Deployment controller", func() {
namespace = testutil.SetOdigosInstrumentationEnabled(testutil.NewMockNamespace())
Expect(k8sClient.Create(ctx, namespace)).Should(Succeed())

source = testutil.NewMockSource(namespace)
Expect(k8sClient.Create(ctx, source)).Should(Succeed())

deployment = testutil.SetOdigosInstrumentationEnabled(testutil.NewMockTestDeployment(namespace))
Expect(k8sClient.Create(ctx, deployment)).Should(Succeed())

source = testutil.NewMockSource(deployment)
Expect(k8sClient.Create(ctx, source)).Should(Succeed())

instrumentationConfig = testutil.NewMockInstrumentationConfig(deployment)
Expect(k8sClient.Create(ctx, instrumentationConfig)).Should(Succeed())
})
Expand Down Expand Up @@ -83,14 +95,20 @@ var _ = Describe("deleteInstrumentationConfig Deployment controller", func() {
deployment = testutil.SetReportedNameAnnotation(deployment, "test")
Expect(k8sClient.Create(ctx, deployment)).Should(Succeed())

source = testutil.NewMockSource(deployment)
Expect(k8sClient.Create(ctx, source)).Should(Succeed())

instrumentationConfig = testutil.NewMockInstrumentationConfig(deployment)
Expect(k8sClient.Create(ctx, instrumentationConfig)).Should(Succeed())
})

It("should delete the reported name annotation on instrumentation label deleted", func() {
It("should delete the reported name annotation on instrumentation label disabled", func() {

deployment = testutil.SetOdigosInstrumentationDisabled(deployment)
Expect(k8sClient.Update(ctx, deployment)).Should(Succeed())
Eventually(func() error {
k8sClient.Get(ctx, client.ObjectKey{Namespace: deployment.GetNamespace(), Name: deployment.GetName()}, deployment)
deployment = testutil.SetOdigosInstrumentationDisabled(deployment)
return k8sClient.Update(ctx, deployment)
}, time.Second*2, time.Millisecond*250).Should(Succeed())
testutil.AssertReportedNameAnnotationDeletedDeployment(ctx, k8sClient, deployment)
})

Expand All @@ -99,6 +117,10 @@ var _ = Describe("deleteInstrumentationConfig Deployment controller", func() {
annotationKey := "test"
annotationValue := "test"

Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: deployment.GetNamespace(), Name: deployment.GetName()}, deployment)).Should(Succeed())
if len(deployment.Annotations) == 0 {
deployment.Annotations = make(map[string]string)
}
deployment.Annotations[annotationKey] = annotationValue
Expect(k8sClient.Update(ctx, deployment)).Should(Succeed())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ import (
"context"
"fmt"

"github.com/odigos-io/odigos/api/odigos/v1alpha1"
odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1"
"github.com/odigos-io/odigos/k8sutils/pkg/workload"
sourceutils "github.com/odigos-io/odigos/k8sutils/pkg/source"

appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -84,23 +83,15 @@ func (r *InstrumentationConfigReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, err
}

instEffectiveEnabled, err := workload.IsWorkloadInstrumentationEffectiveEnabled(ctx, r.Client, workloadObject)
enabled, err := sourceutils.IsObjectInstrumentedBySource(ctx, r.Client, workloadObject)
if err != nil {
logger.Error(err, "error checking if instrumentation is effective")
return ctrl.Result{}, err
}

if !instEffectiveEnabled {
// Check if a Source object exists for this workload
sourceList, err := v1alpha1.GetSources(ctx, r.Client, workloadObject)
if err != nil {
return ctrl.Result{}, err
}
if sourceList.Workload == nil && sourceList.Namespace == nil {
logger.Info("Deleting instrumented application for non-enabled workload")
err := r.Client.Delete(ctx, &instrumentationConfig)
return ctrl.Result{}, client.IgnoreNotFound(err)
}
if !enabled {
logger.Info("Deleting instrumentationconfig for non-enabled workload")
err := r.Client.Delete(ctx, &instrumentationConfig)
return ctrl.Result{}, client.IgnoreNotFound(err)
}

return ctrl.Result{}, nil
Expand Down
Loading
Loading