diff --git a/instrumentor/controllers/instrumentationdevice/common.go b/instrumentor/controllers/instrumentationdevice/common.go index 2a907e3de..879342078 100644 --- a/instrumentor/controllers/instrumentationdevice/common.go +++ b/instrumentor/controllers/instrumentationdevice/common.go @@ -35,6 +35,11 @@ const ( appliedInstrumentationDeviceType = "AppliedInstrumentationDevice" ) +var ( + // can be overridden in tests + GetDefaultSDKs = sdks.GetDefaultSDKs +) + func clearInstrumentationEbpf(obj client.Object) { annotations := obj.GetAnnotations() if annotations == nil { @@ -91,7 +96,7 @@ func addInstrumentationDeviceToWorkload(ctx context.Context, kubeClient client.C } // default otel sdk map according to Odigos tier - otelSdkToUse := sdks.GetDefaultSDKs() + otelSdkToUse := GetDefaultSDKs() for i := range instrumentationRules.Items { instrumentationRule := &instrumentationRules.Items[i] diff --git a/instrumentor/controllers/instrumentationdevice/envoverwiter_test.go b/instrumentor/controllers/instrumentationdevice/envoverwiter_test.go index 044e88215..5d57e8bc0 100644 --- a/instrumentor/controllers/instrumentationdevice/envoverwiter_test.go +++ b/instrumentor/controllers/instrumentationdevice/envoverwiter_test.go @@ -4,6 +4,7 @@ import ( "context" odigosv1 "github.com/odigos-io/odigos/api/odigos/v1alpha1" + "github.com/odigos-io/odigos/api/odigos/v1alpha1/instrumentationrules" "github.com/odigos-io/odigos/common" "github.com/odigos-io/odigos/common/consts" "github.com/odigos-io/odigos/common/envOverwrite" @@ -14,25 +15,8 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/yaml" ) -func GetOdigosConfig(configMap *corev1.ConfigMap, odigosConfig *common.OdigosConfiguration) error { - if err := yaml.Unmarshal([]byte(configMap.Data[consts.OdigosConfigurationFileName]), &odigosConfig); err != nil { - return err - } - return nil -} - -func SetOdigosConfig(configMap *corev1.ConfigMap, odigosConfig *common.OdigosConfiguration) error { - data, err := yaml.Marshal(odigosConfig) - if err != nil { - return err - } - configMap.Data[consts.OdigosConfigurationFileName] = string(data) - return nil -} - var _ = Describe("envoverwrite", func() { ctx := context.Background() var namespace *corev1.Namespace @@ -56,13 +40,8 @@ var _ = Describe("envoverwrite", func() { }) AfterEach(func() { - // restore odigos config to it's original state - var cm corev1.ConfigMap - var odigosConfig common.OdigosConfiguration - Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: consts.DefaultOdigosNamespace, Name: consts.OdigosConfigurationName}, &cm)).Should(Succeed()) - GetOdigosConfig(&cm, &odigosConfig) - SetOdigosConfig(&cm, &odigosConfig) - Expect(k8sClient.Update(ctx, &cm)).Should(Succeed()) + // restore to the default SDK + testutil.SetDefaultSDK(testProgrammingLanguagePython, common.OtelSdkNativeCommunity) }) Describe("User did not set env in manifest or docker image", func() { @@ -149,12 +128,7 @@ var _ = Describe("envoverwrite", func() { It("Should not add the unrelated env vars with different otel SDKs", func() { // make the SDK for python and java different - var cm corev1.ConfigMap - var odigosConfig common.OdigosConfiguration - Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: consts.DefaultOdigosNamespace, Name: consts.OdigosConfigurationName}, &cm)).Should(Succeed()) - GetOdigosConfig(&cm, &odigosConfig) - SetOdigosConfig(&cm, &odigosConfig) - Expect(k8sClient.Update(ctx, &cm)).Should(Succeed()) + testutil.SetDefaultSDK(common.JavaProgrammingLanguage, common.OtelSdkEbpfEnterprise) instrumentedApplication = testutil.SetInstrumentedApplicationContainer(testutil.NewMockInstrumentedApplication(deployment), &testEnvVarPythonPath, &userEnvValue, common.JavaProgrammingLanguage) Expect(k8sClient.Create(ctx, instrumentedApplication)).Should(Succeed()) @@ -228,14 +202,25 @@ var _ = Describe("envoverwrite", func() { When("Default SDK changes to another SDK", func() { newSdk := common.OtelSdkEbpfEnterprise + const ruleName = "test-instrumentation-rule" BeforeEach(func() { - var cm corev1.ConfigMap - var odigosConfig common.OdigosConfiguration - Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: consts.DefaultOdigosNamespace, Name: consts.OdigosConfigurationName}, &cm)).Should(Succeed()) - GetOdigosConfig(&cm, &odigosConfig) - SetOdigosConfig(&cm, &odigosConfig) - Expect(k8sClient.Update(ctx, &cm)).Should(Succeed()) + // change the default SDK to another SDK by creating a rule + rule := testutil.NewMockEmptyInstrumentationRule(ruleName, consts.DefaultOdigosNamespace) + Expect(k8sClient.Create(ctx, rule)).Should(Succeed()) + rule.Spec.OtelSdks = &instrumentationrules.OtelSdks{ + OtelSdkByLanguage: map[common.ProgrammingLanguage]common.OtelSdk{ + testProgrammingLanguagePython: newSdk, + }, + } + Expect(k8sClient.Update(ctx, rule)).Should(Succeed()) + }) + + AfterEach(func() { + // revert the default SDK back to the original value by deleting the rule + var rule odigosv1.InstrumentationRule + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: ruleName, Namespace: consts.DefaultOdigosNamespace}, &rule)).Should(Succeed()) + Expect(k8sClient.Delete(ctx, &rule)).Should(Succeed()) }) It("Should update the manifest with new odigos env value", func() { @@ -243,7 +228,7 @@ var _ = Describe("envoverwrite", func() { Expect(found).Should(BeTrue()) newMergedEnvValue := userEnvValue + ":" + newOdigosValue - // after the odigos config is updated, the deployment should be updated with the new odigos value + // after the SDK is updated, the deployment should be updated with the new odigos value testutil.AssertDepContainerSingleEnv(ctx, k8sClient, deployment, testEnvVarPythonPath, newMergedEnvValue) // when uninstrumented, the value should be reverted to the original value which was in the manifest diff --git a/instrumentor/controllers/instrumentationdevice/suite_test.go b/instrumentor/controllers/instrumentationdevice/suite_test.go index c8caedc57..314fc1523 100644 --- a/instrumentor/controllers/instrumentationdevice/suite_test.go +++ b/instrumentor/controllers/instrumentationdevice/suite_test.go @@ -23,6 +23,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook" + "github.com/odigos-io/odigos/common" "github.com/odigos-io/odigos/instrumentor/internal/testutil" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -41,11 +42,12 @@ import ( ) var ( - cfg *rest.Config - k8sClient client.Client - testEnv *envtest.Environment - testCtx context.Context - cancel context.CancelFunc + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + testCtx context.Context + cancel context.CancelFunc + origGetDefaultSDKs func() map[common.ProgrammingLanguage]common.OtelSdk ) func TestControllers(t *testing.T) { @@ -92,8 +94,8 @@ var _ = BeforeSuite(func() { Expect(k8sClient.Status().Update(testCtx, datacollection)).Should(Succeed()) // create odigos configuration with default sdks - odigosConfiguration := testutil.NewMockOdigosConfig() - Expect(k8sClient.Create(testCtx, odigosConfiguration)).Should(Succeed()) + origGetDefaultSDKs = instrumentationdevice.GetDefaultSDKs + instrumentationdevice.GetDefaultSDKs = testutil.MockGetDefaultSDKs webhookInstallOptions := &testEnv.WebhookInstallOptions k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ @@ -122,4 +124,5 @@ var _ = AfterSuite(func() { By("tearing down the test environment") err := testEnv.Stop() Expect(err).NotTo(HaveOccurred()) + instrumentationdevice.GetDefaultSDKs = origGetDefaultSDKs }) diff --git a/instrumentor/internal/testutil/mocks.go b/instrumentor/internal/testutil/mocks.go index ba6afb623..946a61489 100644 --- a/instrumentor/internal/testutil/mocks.go +++ b/instrumentor/internal/testutil/mocks.go @@ -1,7 +1,6 @@ package testutil import ( - "encoding/json" "fmt" "github.com/google/uuid" @@ -12,7 +11,6 @@ import ( "github.com/odigos-io/odigos/k8sutils/pkg/workload" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" @@ -26,6 +24,10 @@ const ( mockStatefulSetName = "test-statefulset" ) +var ( + mockDefaultSDKs = map[common.ProgrammingLanguage]common.OtelSdk{} +) + func NewOdigosSystemNamespace() *corev1.Namespace { return &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ @@ -152,32 +154,24 @@ func NewMockInstrumentedApplication(workloadObject client.Object) *odigosv1.Inst } } -func NewMockDataCollection() *odigosv1.CollectorsGroup { - return &odigosv1.CollectorsGroup{ +func NewMockEmptyInstrumentationRule(name, ns string) *odigosv1.InstrumentationRule { + return &odigosv1.InstrumentationRule{ ObjectMeta: metav1.ObjectMeta{ - Name: k8sconsts.OdigosNodeCollectorDaemonSetName, - Namespace: consts.DefaultOdigosNamespace, - }, - Spec: odigosv1.CollectorsGroupSpec{ - Role: odigosv1.CollectorsGroupRoleNodeCollector, + Name: name, + Namespace: ns, }, + Spec: odigosv1.InstrumentationRuleSpec{}, } } -func NewMockOdigosConfig() *v1.ConfigMap { - config, _ := json.Marshal(common.OdigosConfiguration{}) - - return &v1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, +func NewMockDataCollection() *odigosv1.CollectorsGroup { + return &odigosv1.CollectorsGroup{ ObjectMeta: metav1.ObjectMeta{ - Name: consts.OdigosConfigurationName, + Name: k8sconsts.OdigosNodeCollectorDaemonSetName, Namespace: consts.DefaultOdigosNamespace, }, - Data: map[string]string{ - consts.OdigosConfigurationFileName: string(config), + Spec: odigosv1.CollectorsGroupSpec{ + Role: odigosv1.CollectorsGroupRoleNodeCollector, }, } } @@ -187,3 +181,11 @@ func NewMockOdigosConfig() *v1.ConfigMap { func generateUUIDNamespace(baseName string) string { return fmt.Sprintf("%s-%s", baseName, uuid.New().String()) } + +func MockGetDefaultSDKs() map[common.ProgrammingLanguage]common.OtelSdk { + return mockDefaultSDKs +} + +func SetDefaultSDK(language common.ProgrammingLanguage, sdk common.OtelSdk) { + mockDefaultSDKs[language] = sdk +} diff --git a/instrumentor/sdks/sdks.go b/instrumentor/sdks/sdks.go index 1bf711398..ab6de55f5 100644 --- a/instrumentor/sdks/sdks.go +++ b/instrumentor/sdks/sdks.go @@ -43,7 +43,7 @@ func otelSdkConfigOnPrem() map[common.ProgrammingLanguage]common.OtelSdk { } } -func SetDefaultSDKs(ctx context.Context, clientset *kubernetes.Clientset) error { +func SetDefaultSDKs(ctx context.Context, clientset *kubernetes.Clientset) error { odigosTier, err := k8sutils.GetCurrentOdigosTier(ctx, env.GetCurrentNamespace(), clientset) if err != nil { return err @@ -63,4 +63,4 @@ func SetDefaultSDKs(ctx context.Context, clientset *kubernetes.Clientset) error func GetDefaultSDKs() map[common.ProgrammingLanguage]common.OtelSdk { return defaultOtelSdkPerLanguage -} \ No newline at end of file +}