From b593fa773fdcff042d00ea265ea5553054c793a2 Mon Sep 17 00:00:00 2001 From: Avadhut Pisal Date: Wed, 12 Oct 2022 18:13:43 +0530 Subject: [PATCH] Validate all env. vars. before starting injecting env. vars (#1141) * skips env var injection and sdk configurations if agent injection is skipped * mutate container at the last of SDK injection step * validate first and then mutate the container with env variables * fixes go lint issues * incorporates review comments * fixes go lint issue * removes return statement in case of failed instrumentation --- pkg/instrumentation/dotnet.go | 65 +++++------- pkg/instrumentation/dotnet_test.go | 138 ++------------------------ pkg/instrumentation/javaagent.go | 24 ++--- pkg/instrumentation/javaagent_test.go | 9 +- pkg/instrumentation/nodejs.go | 22 ++-- pkg/instrumentation/nodejs_test.go | 9 +- pkg/instrumentation/python.go | 24 ++--- pkg/instrumentation/python_test.go | 9 +- pkg/instrumentation/sdk.go | 69 +++++++++---- 9 files changed, 132 insertions(+), 237 deletions(-) diff --git a/pkg/instrumentation/dotnet.go b/pkg/instrumentation/dotnet.go index 210db334f0..47263bb91a 100644 --- a/pkg/instrumentation/dotnet.go +++ b/pkg/instrumentation/dotnet.go @@ -17,7 +17,6 @@ package instrumentation import ( "fmt" - "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" @@ -40,11 +39,17 @@ const ( dotNetStartupHookPath = "/otel-auto-instrumentation/netcoreapp3.1/OpenTelemetry.AutoInstrumentation.StartupHook.dll" ) -func injectDotNetSDK(logger logr.Logger, dotNetSpec v1alpha1.DotNet, pod corev1.Pod, index int) corev1.Pod { - // caller checks if there is at least one container - container := pod.Spec.Containers[index] +func injectDotNetSDK(dotNetSpec v1alpha1.DotNet, pod corev1.Pod, index int) (corev1.Pod, error) { - // inject env vars + // caller checks if there is at least one container. + container := &pod.Spec.Containers[index] + + err := validateContainerEnv(container.Env, envDotNetStartupHook, envDotNetAdditionalDeps, envDotNetSharedStore) + if err != nil { + return pod, err + } + + // inject .NET instrumentation spec env vars. for _, env := range dotNetSpec.Env { idx := getIndexOfEnv(container.Env, env.Name) if idx == -1 { @@ -57,40 +62,26 @@ func injectDotNetSDK(logger logr.Logger, dotNetSpec v1alpha1.DotNet, pod corev1. concatEnvValues = true ) - if !trySetEnvVar(logger, &container, envDotNetCoreClrEnableProfiling, dotNetCoreClrEnableProfilingEnabled, doNotConcatEnvValues) { - return pod - } + setDotNetEnvVar(container, envDotNetCoreClrEnableProfiling, dotNetCoreClrEnableProfilingEnabled, doNotConcatEnvValues) - if !trySetEnvVar(logger, &container, envDotNetCoreClrProfiler, dotNetCoreClrProfilerId, doNotConcatEnvValues) { - return pod - } + setDotNetEnvVar(container, envDotNetCoreClrProfiler, dotNetCoreClrProfilerId, doNotConcatEnvValues) - if !trySetEnvVar(logger, &container, envDotNetCoreClrProfilerPath, dotNetCoreClrProfilerPath, doNotConcatEnvValues) { - return pod - } + setDotNetEnvVar(container, envDotNetCoreClrProfilerPath, dotNetCoreClrProfilerPath, doNotConcatEnvValues) - if !trySetEnvVar(logger, &container, envDotNetStartupHook, dotNetStartupHookPath, concatEnvValues) { - return pod - } + setDotNetEnvVar(container, envDotNetStartupHook, dotNetStartupHookPath, concatEnvValues) - if !trySetEnvVar(logger, &container, envDotNetAdditionalDeps, dotNetAdditionalDepsPath, concatEnvValues) { - return pod - } + setDotNetEnvVar(container, envDotNetAdditionalDeps, dotNetAdditionalDepsPath, concatEnvValues) - if !trySetEnvVar(logger, &container, envDotNetOTelAutoHome, dotNetOTelAutoHomePath, doNotConcatEnvValues) { - return pod - } + setDotNetEnvVar(container, envDotNetOTelAutoHome, dotNetOTelAutoHomePath, doNotConcatEnvValues) - if !trySetEnvVar(logger, &container, envDotNetSharedStore, dotNetSharedStorePath, concatEnvValues) { - return pod - } + setDotNetEnvVar(container, envDotNetSharedStore, dotNetSharedStorePath, concatEnvValues) container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ Name: volumeName, MountPath: "/otel-auto-instrumentation", }) - // We just inject Volumes and init containers for the first processed container + // We just inject Volumes and init containers for the first processed container. if isInitContainerMissing(pod) { pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ Name: volumeName, @@ -108,30 +99,22 @@ func injectDotNetSDK(logger logr.Logger, dotNetSpec v1alpha1.DotNet, pod corev1. }}, }) } - - pod.Spec.Containers[index] = container - return pod + return pod, nil } -func trySetEnvVar(logger logr.Logger, container *corev1.Container, envVarName string, envVarValue string, concatValues bool) bool { +// setDotNetEnvVar function sets env var to the container if not exist already. +// value of concatValues should be set to true if the env var supports multiple values separated by :. +// If it is set to false, the original container's env var value has priority. +func setDotNetEnvVar(container *corev1.Container, envVarName string, envVarValue string, concatValues bool) { idx := getIndexOfEnv(container.Env, envVarName) if idx < 0 { container.Env = append(container.Env, corev1.EnvVar{ Name: envVarName, Value: envVarValue, }) - return true + return } - - if container.Env[idx].ValueFrom != nil { - // TODO add to status object or submit it as an event - logger.Info("Skipping DotNet SDK injection, the container defines env var value via ValueFrom", "envVar", envVarName, "container", container.Name) - return false - } - if concatValues { container.Env[idx].Value = fmt.Sprintf("%s:%s", container.Env[idx].Value, envVarValue) } - - return true } diff --git a/pkg/instrumentation/dotnet_test.go b/pkg/instrumentation/dotnet_test.go index 00177e15f0..aa0978c985 100644 --- a/pkg/instrumentation/dotnet_test.go +++ b/pkg/instrumentation/dotnet_test.go @@ -18,7 +18,6 @@ import ( "fmt" "testing" - "github.com/go-logr/logr" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -31,6 +30,7 @@ func TestInjectDotNetSDK(t *testing.T) { v1alpha1.DotNet pod corev1.Pod expected corev1.Pod + err error }{ { name: "CORECLR_ENABLE_PROFILING, CORECLR_PROFILER, CORECLR_PROFILER_PATH, DOTNET_STARTUP_HOOKS, DOTNET_SHARED_STORE, DOTNET_ADDITIONAL_DEPS, OTEL_DOTNET_AUTO_HOME not defined", @@ -105,6 +105,7 @@ func TestInjectDotNetSDK(t *testing.T) { }, }, }, + err: nil, }, { name: "CORECLR_ENABLE_PROFILING, CORECLR_PROFILER, CORECLR_PROFILER_PATH, DOTNET_STARTUP_HOOKS, DOTNET_ADDITIONAL_DEPS, DOTNET_SHARED_STORE, OTEL_DOTNET_AUTO_HOME defined", @@ -210,102 +211,7 @@ func TestInjectDotNetSDK(t *testing.T) { }, }, }, - }, - { - name: "CORECLR_ENABLE_PROFILING defined as ValueFrom", - DotNet: v1alpha1.DotNet{Image: "foo/bar:1"}, - pod: corev1.Pod{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Env: []corev1.EnvVar{ - { - Name: envDotNetCoreClrEnableProfiling, - ValueFrom: &corev1.EnvVarSource{}, - }, - }, - }, - }, - }, - }, - expected: corev1.Pod{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Env: []corev1.EnvVar{ - { - Name: envDotNetCoreClrEnableProfiling, - ValueFrom: &corev1.EnvVarSource{}, - }, - }, - }, - }, - }, - }, - }, - { - name: "CORECLR_PROFILER defined as ValueFrom", - DotNet: v1alpha1.DotNet{Image: "foo/bar:1"}, - pod: corev1.Pod{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Env: []corev1.EnvVar{ - { - Name: envDotNetCoreClrProfiler, - ValueFrom: &corev1.EnvVarSource{}, - }, - }, - }, - }, - }, - }, - expected: corev1.Pod{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Env: []corev1.EnvVar{ - { - Name: envDotNetCoreClrProfiler, - ValueFrom: &corev1.EnvVarSource{}, - }, - }, - }, - }, - }, - }, - }, - { - name: "CORECLR_PROFILER_PATH defined as ValueFrom", - DotNet: v1alpha1.DotNet{Image: "foo/bar:1"}, - pod: corev1.Pod{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Env: []corev1.EnvVar{ - { - Name: envDotNetCoreClrProfilerPath, - ValueFrom: &corev1.EnvVarSource{}, - }, - }, - }, - }, - }, - }, - expected: corev1.Pod{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Env: []corev1.EnvVar{ - { - Name: envDotNetCoreClrProfilerPath, - ValueFrom: &corev1.EnvVarSource{}, - }, - }, - }, - }, - }, - }, + err: nil, }, { name: "DOTNET_STARTUP_HOOKS defined as ValueFrom", @@ -338,6 +244,7 @@ func TestInjectDotNetSDK(t *testing.T) { }, }, }, + err: fmt.Errorf("the container defines env var value via ValueFrom, envVar: %s", envDotNetStartupHook), }, { name: "DOTNET_ADDITIONAL_DEPS defined as ValueFrom", @@ -370,6 +277,7 @@ func TestInjectDotNetSDK(t *testing.T) { }, }, }, + err: fmt.Errorf("the container defines env var value via ValueFrom, envVar: %s", envDotNetAdditionalDeps), }, { name: "DOTNET_SHARED_STORE defined as ValueFrom", @@ -402,45 +310,15 @@ func TestInjectDotNetSDK(t *testing.T) { }, }, }, - }, - { - name: "OTEL_DOTNET_AUTO_HOME defined as ValueFrom", - DotNet: v1alpha1.DotNet{Image: "foo/bar:1"}, - pod: corev1.Pod{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Env: []corev1.EnvVar{ - { - Name: envDotNetOTelAutoHome, - ValueFrom: &corev1.EnvVarSource{}, - }, - }, - }, - }, - }, - }, - expected: corev1.Pod{ - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Env: []corev1.EnvVar{ - { - Name: envDotNetOTelAutoHome, - ValueFrom: &corev1.EnvVarSource{}, - }, - }, - }, - }, - }, - }, + err: fmt.Errorf("the container defines env var value via ValueFrom, envVar: %s", envDotNetSharedStore), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - pod := injectDotNetSDK(logr.Discard(), test.DotNet, test.pod, 0) + pod, err := injectDotNetSDK(test.DotNet, test.pod, 0) assert.Equal(t, test.expected, pod) + assert.Equal(t, test.err, err) }) } } diff --git a/pkg/instrumentation/javaagent.go b/pkg/instrumentation/javaagent.go index 1d534a4b1d..02688ac0d9 100644 --- a/pkg/instrumentation/javaagent.go +++ b/pkg/instrumentation/javaagent.go @@ -15,7 +15,6 @@ package instrumentation import ( - "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" @@ -26,11 +25,16 @@ const ( javaJVMArgument = " -javaagent:/otel-auto-instrumentation/javaagent.jar" ) -func injectJavaagent(logger logr.Logger, javaSpec v1alpha1.Java, pod corev1.Pod, index int) corev1.Pod { - // caller checks if there is at least one container +func injectJavaagent(javaSpec v1alpha1.Java, pod corev1.Pod, index int) (corev1.Pod, error) { + // caller checks if there is at least one container. container := &pod.Spec.Containers[index] - // inject env vars + err := validateContainerEnv(container.Env, envJavaToolsOptions) + if err != nil { + return pod, err + } + + // inject Java instrumentation spec env vars. for _, env := range javaSpec.Env { idx := getIndexOfEnv(container.Env, env.Name) if idx == -1 { @@ -45,14 +49,7 @@ func injectJavaagent(logger logr.Logger, javaSpec v1alpha1.Java, pod corev1.Pod, Value: javaJVMArgument, }) } else { - if container.Env[idx].ValueFrom != nil { - // TODO add to status object or submit it as an event - logger.Info("Skipping javaagent injection, the container defines JAVA_TOOL_OPTIONS env var value via ValueFrom", "container", container.Name) - return pod - } - container.Env[idx].Value = container.Env[idx].Value + javaJVMArgument - } container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ @@ -60,7 +57,7 @@ func injectJavaagent(logger logr.Logger, javaSpec v1alpha1.Java, pod corev1.Pod, MountPath: "/otel-auto-instrumentation", }) - // We just inject Volumes and init containers for the first processed container + // We just inject Volumes and init containers for the first processed container. if isInitContainerMissing(pod) { pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ Name: volumeName, @@ -78,6 +75,5 @@ func injectJavaagent(logger logr.Logger, javaSpec v1alpha1.Java, pod corev1.Pod, }}, }) } - - return pod + return pod, err } diff --git a/pkg/instrumentation/javaagent_test.go b/pkg/instrumentation/javaagent_test.go index d97853bbfb..ab3a6f885d 100644 --- a/pkg/instrumentation/javaagent_test.go +++ b/pkg/instrumentation/javaagent_test.go @@ -15,9 +15,9 @@ package instrumentation import ( + "fmt" "testing" - "github.com/go-logr/logr" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -30,6 +30,7 @@ func TestInjectJavaagent(t *testing.T) { v1alpha1.Java pod corev1.Pod expected corev1.Pod + err error }{ { name: "JAVA_TOOL_OPTIONS not defined", @@ -80,6 +81,7 @@ func TestInjectJavaagent(t *testing.T) { }, }, }, + err: nil, }, { name: "JAVA_TOOL_OPTIONS defined", @@ -137,6 +139,7 @@ func TestInjectJavaagent(t *testing.T) { }, }, }, + err: nil, }, { name: "JAVA_TOOL_OPTIONS defined as ValueFrom", @@ -169,13 +172,15 @@ func TestInjectJavaagent(t *testing.T) { }, }, }, + err: fmt.Errorf("the container defines env var value via ValueFrom, envVar: %s", envJavaToolsOptions), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - pod := injectJavaagent(logr.Discard(), test.Java, test.pod, 0) + pod, err := injectJavaagent(test.Java, test.pod, 0) assert.Equal(t, test.expected, pod) + assert.Equal(t, test.err, err) }) } } diff --git a/pkg/instrumentation/nodejs.go b/pkg/instrumentation/nodejs.go index 5a26fd6adf..d1a4e180e0 100644 --- a/pkg/instrumentation/nodejs.go +++ b/pkg/instrumentation/nodejs.go @@ -15,7 +15,6 @@ package instrumentation import ( - "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" @@ -26,11 +25,16 @@ const ( nodeRequireArgument = " --require /otel-auto-instrumentation/autoinstrumentation.js" ) -func injectNodeJSSDK(logger logr.Logger, nodeJSSpec v1alpha1.NodeJS, pod corev1.Pod, index int) corev1.Pod { - // caller checks if there is at least one container +func injectNodeJSSDK(nodeJSSpec v1alpha1.NodeJS, pod corev1.Pod, index int) (corev1.Pod, error) { + // caller checks if there is at least one container. container := &pod.Spec.Containers[index] - // inject env vars + err := validateContainerEnv(container.Env, envNodeOptions) + if err != nil { + return pod, err + } + + // inject NodeJS instrumentation spec env vars. for _, env := range nodeJSSpec.Env { idx := getIndexOfEnv(container.Env, env.Name) if idx == -1 { @@ -45,14 +49,7 @@ func injectNodeJSSDK(logger logr.Logger, nodeJSSpec v1alpha1.NodeJS, pod corev1. Value: nodeRequireArgument, }) } else if idx > -1 { - if container.Env[idx].ValueFrom != nil { - // TODO add to status object or submit it as an event - logger.Info("Skipping NodeJS SDK injection, the container defines NODE_OPTIONS env var value via ValueFrom", "container", container.Name) - return pod - } - container.Env[idx].Value = container.Env[idx].Value + nodeRequireArgument - } container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ @@ -78,6 +75,5 @@ func injectNodeJSSDK(logger logr.Logger, nodeJSSpec v1alpha1.NodeJS, pod corev1. }}, }) } - - return pod + return pod, nil } diff --git a/pkg/instrumentation/nodejs_test.go b/pkg/instrumentation/nodejs_test.go index e0a187f0ab..3054f029a9 100644 --- a/pkg/instrumentation/nodejs_test.go +++ b/pkg/instrumentation/nodejs_test.go @@ -15,9 +15,9 @@ package instrumentation import ( + "fmt" "testing" - "github.com/go-logr/logr" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -30,6 +30,7 @@ func TestInjectNodeJSSDK(t *testing.T) { v1alpha1.NodeJS pod corev1.Pod expected corev1.Pod + err error }{ { name: "NODE_OPTIONS not defined", @@ -80,6 +81,7 @@ func TestInjectNodeJSSDK(t *testing.T) { }, }, }, + err: nil, }, { name: "NODE_OPTIONS defined", @@ -137,6 +139,7 @@ func TestInjectNodeJSSDK(t *testing.T) { }, }, }, + err: nil, }, { name: "NODE_OPTIONS defined as ValueFrom", @@ -169,13 +172,15 @@ func TestInjectNodeJSSDK(t *testing.T) { }, }, }, + err: fmt.Errorf("the container defines env var value via ValueFrom, envVar: %s", envNodeOptions), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - pod := injectNodeJSSDK(logr.Discard(), test.NodeJS, test.pod, 0) + pod, err := injectNodeJSSDK(test.NodeJS, test.pod, 0) assert.Equal(t, test.expected, pod) + assert.Equal(t, test.err, err) }) } } diff --git a/pkg/instrumentation/python.go b/pkg/instrumentation/python.go index b3956e3530..2662ddc877 100644 --- a/pkg/instrumentation/python.go +++ b/pkg/instrumentation/python.go @@ -17,7 +17,6 @@ package instrumentation import ( "fmt" - "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" @@ -31,11 +30,16 @@ const ( pythonPathSuffix = "/otel-auto-instrumentation" ) -func injectPythonSDK(logger logr.Logger, pythonSpec v1alpha1.Python, pod corev1.Pod, index int) corev1.Pod { - // caller checks if there is at least one container +func injectPythonSDK(pythonSpec v1alpha1.Python, pod corev1.Pod, index int) (corev1.Pod, error) { + // caller checks if there is at least one container. container := &pod.Spec.Containers[index] - // inject env vars + err := validateContainerEnv(container.Env, envPythonPath) + if err != nil { + return pod, err + } + + // inject Python instrumentation spec env vars. for _, env := range pythonSpec.Env { idx := getIndexOfEnv(container.Env, env.Name) if idx == -1 { @@ -50,14 +54,7 @@ func injectPythonSDK(logger logr.Logger, pythonSpec v1alpha1.Python, pod corev1. Value: fmt.Sprintf("%s:%s", pythonPathPrefix, pythonPathSuffix), }) } else if idx > -1 { - if container.Env[idx].ValueFrom != nil { - // TODO add to status object or submit it as an event - logger.Info("Skipping Python SDK injection, the container defines PYTHONPATH env var value via ValueFrom", "container", container.Name) - return pod - } - container.Env[idx].Value = fmt.Sprintf("%s:%s:%s", pythonPathPrefix, container.Env[idx].Value, pythonPathSuffix) - } // Set OTEL_TRACES_EXPORTER to HTTP exporter if not set by user because it is what our autoinstrumentation supports. @@ -86,7 +83,7 @@ func injectPythonSDK(logger logr.Logger, pythonSpec v1alpha1.Python, pod corev1. MountPath: "/otel-auto-instrumentation", }) - // We just inject Volumes and init containers for the first processed container + // We just inject Volumes and init containers for the first processed container. if isInitContainerMissing(pod) { pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ Name: volumeName, @@ -104,6 +101,5 @@ func injectPythonSDK(logger logr.Logger, pythonSpec v1alpha1.Python, pod corev1. }}, }) } - - return pod + return pod, nil } diff --git a/pkg/instrumentation/python_test.go b/pkg/instrumentation/python_test.go index c8a4887a19..35e8e4d34e 100644 --- a/pkg/instrumentation/python_test.go +++ b/pkg/instrumentation/python_test.go @@ -18,7 +18,6 @@ import ( "fmt" "testing" - "github.com/go-logr/logr" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -31,6 +30,7 @@ func TestInjectPythonSDK(t *testing.T) { v1alpha1.Python pod corev1.Pod expected corev1.Pod + err error }{ { name: "PYTHONPATH not defined", @@ -89,6 +89,7 @@ func TestInjectPythonSDK(t *testing.T) { }, }, }, + err: nil, }, { name: "PYTHONPATH defined", @@ -154,6 +155,7 @@ func TestInjectPythonSDK(t *testing.T) { }, }, }, + err: nil, }, { name: "OTEL_TRACES_EXPORTER defined", @@ -284,6 +286,7 @@ func TestInjectPythonSDK(t *testing.T) { }, }, }, + err: nil, }, { name: "PYTHONPATH defined as ValueFrom", @@ -316,13 +319,15 @@ func TestInjectPythonSDK(t *testing.T) { }, }, }, + err: fmt.Errorf("the container defines env var value via ValueFrom, envVar: %s", envPythonPath), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - pod := injectPythonSDK(logr.Discard(), test.Python, test.pod, 0) + pod, err := injectPythonSDK(test.Python, test.pod, 0) assert.Equal(t, test.expected, pod) + assert.Equal(t, test.err, err) }) } } diff --git a/pkg/instrumentation/sdk.go b/pkg/instrumentation/sdk.go index 346fc77681..b126427d75 100644 --- a/pkg/instrumentation/sdk.go +++ b/pkg/instrumentation/sdk.go @@ -64,35 +64,53 @@ func (i *sdkInjector) inject(ctx context.Context, insts languageInstrumentations } } - // inject only to the first container for now - // in the future we can define an annotation to configure this if insts.Java != nil { otelinst := *insts.Java - i.logger.V(1).Info("injecting java instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name) - pod = injectJavaagent(i.logger, otelinst.Spec.Java, pod, index) - pod = i.injectCommonEnvVar(otelinst, pod, index) - pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) + var err error + i.logger.V(1).Info("injecting Java instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name) + pod, err = injectJavaagent(otelinst.Spec.Java, pod, index) + if err != nil { + i.logger.Info("Skipping javaagent injection", "reason", err.Error(), "container", pod.Spec.Containers[index].Name) + } else { + pod = i.injectCommonEnvVar(otelinst, pod, index) + pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) + } } if insts.NodeJS != nil { otelinst := *insts.NodeJS - i.logger.V(1).Info("injecting nodejs instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name) - pod = injectNodeJSSDK(i.logger, otelinst.Spec.NodeJS, pod, index) - pod = i.injectCommonEnvVar(otelinst, pod, index) - pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) + var err error + i.logger.V(1).Info("injecting NodeJS instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name) + pod, err = injectNodeJSSDK(otelinst.Spec.NodeJS, pod, index) + if err != nil { + i.logger.Info("Skipping NodeJS SDK injection", "reason", err.Error(), "container", pod.Spec.Containers[index].Name) + } else { + pod = i.injectCommonEnvVar(otelinst, pod, index) + pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) + } } if insts.Python != nil { otelinst := *insts.Python - i.logger.V(1).Info("injecting python instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name) - pod = injectPythonSDK(i.logger, otelinst.Spec.Python, pod, index) - pod = i.injectCommonEnvVar(otelinst, pod, index) - pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) + var err error + i.logger.V(1).Info("injecting Python instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name) + pod, err = injectPythonSDK(otelinst.Spec.Python, pod, index) + if err != nil { + i.logger.Info("Skipping Python SDK injection", "reason", err.Error(), "container", pod.Spec.Containers[index].Name) + } else { + pod = i.injectCommonEnvVar(otelinst, pod, index) + pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) + } } if insts.DotNet != nil { otelinst := *insts.DotNet - i.logger.V(1).Info("injecting dotnet instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name) - pod = injectDotNetSDK(i.logger, otelinst.Spec.DotNet, pod, index) - pod = i.injectCommonEnvVar(otelinst, pod, index) - pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) + var err error + i.logger.V(1).Info("injecting DotNet instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name) + pod, err = injectDotNetSDK(otelinst.Spec.DotNet, pod, index) + if err != nil { + i.logger.Info("Skipping DotNet SDK injection", "reason", err.Error(), "container", pod.Spec.Containers[index].Name) + } else { + pod = i.injectCommonEnvVar(otelinst, pod, index) + pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) + } } if insts.Sdk != nil { otelinst := *insts.Sdk @@ -100,7 +118,6 @@ func (i *sdkInjector) inject(ctx context.Context, insts languageInstrumentations pod = i.injectCommonEnvVar(otelinst, pod, index) pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index) } - return pod } @@ -377,3 +394,17 @@ func moveEnvToListEnd(envs []corev1.EnvVar, idx int) []corev1.EnvVar { return envs } + +func validateContainerEnv(envs []corev1.EnvVar, envsToBeValidated ...string) error { + for _, envToBeValidated := range envsToBeValidated { + for _, containerEnv := range envs { + if containerEnv.Name == envToBeValidated { + if containerEnv.ValueFrom != nil { + return fmt.Errorf("the container defines env var value via ValueFrom, envVar: %s", containerEnv.Name) + } + break + } + } + } + return nil +}