diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 065e2ad4..d7461010 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -181,6 +181,8 @@ jobs: with: context: . platforms: linux/amd64,linux/arm64,linux/arm + build-args: | + K8S_AGENTS_OPERATOR_VERSION=${{ steps.metadata.outputs.version }} file: ./Dockerfile push: ${{ github.event_name != 'pull_request' && !startsWith(github.ref, 'refs/heads/renovate') }} tags: ${{ steps.metadata.outputs.tags }} diff --git a/Dockerfile b/Dockerfile index f74cda6d..2f7a0ea8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM --platform=$BUILDPLATFORM golang:1.23.2-bookworm@sha256:2341ddffd3eddb72e0aebab476222fbc24d4a507c4d490a51892ec861bdb71fc AS builder +FROM --platform=$BUILDPLATFORM golang:1.23.3-bookworm@sha256:3f3b9daa3de608f3e869cd2ff8baf21555cf0fca9fd34251b8f340f9b7c30ec5 AS builder WORKDIR /app @@ -15,8 +15,9 @@ ARG TARGETOS ARG TARGETARCH ARG GOOS=$TARGETOS ARG GOARCH=$TARGETARCH +ARG K8S_AGENTS_OPERATOR_VERSION="development" -RUN make build +RUN make build K8S_AGENTS_OPERATOR_VERSION="${K8S_AGENTS_OPERATOR_VERSION}" # Use minimal base image to package the operator # Source: https://github.com/GoogleContainerTools/distroless diff --git a/Makefile b/Makefile index 2f9fea12..4429cada 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,8 @@ LICENSE_KEY ?= fake-abc123 E2E_K8S_VERSION ?= v1.31.1 ALL_E2E_K8S_VERSIONS ?= v1.31.1 v1.30.5 v1.29.9 v1.28.14 v1.27.16 v1.26.15 +K8S_AGENTS_OPERATOR_VERSION = "" + .DEFAULT_GOAL := help # Go packages to test @@ -158,7 +160,7 @@ go-format: ## Format all go files .PHONY: build build: ## Build the go binary - CGO_ENABLED=0 go build -o $(BIN_DIR)/operator $(GO_DIR) + CGO_ENABLED=0 go build -ldflags="-X 'github.com/newrelic/k8s-agents-operator/src/internal/version.version=$(K8S_AGENTS_OPERATOR_VERSION)' -X 'github.com/newrelic/k8s-agents-operator/src/internal/version.buildDate=$(shell date)'" -o $(BIN_DIR)/operator $(GO_DIR) .PHONY: dockerbuild dockerbuild: ## Build the docker image diff --git a/go.mod b/go.mod index 3e20657a..f474679a 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/newrelic/k8s-agents-operator -go 1.23.2 +go 1.23.3 require ( github.com/go-logr/logr v1.4.2 github.com/google/go-cmp v0.6.0 github.com/onsi/ginkgo/v2 v2.21.0 github.com/onsi/gomega v1.35.1 - github.com/openshift/api v0.0.0-20241107155230-d37bb9f7e380 + github.com/openshift/api v0.0.0-20241120064718-caf97963ed30 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 go.opentelemetry.io/otel v1.31.0 diff --git a/go.sum b/go.sum index bddd35c5..095bf383 100644 --- a/go.sum +++ b/go.sum @@ -92,6 +92,8 @@ github.com/openshift/api v0.0.0-20241106222702-2429e35d6633 h1:JgeV16qlZA9YRrfPq github.com/openshift/api v0.0.0-20241106222702-2429e35d6633/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= github.com/openshift/api v0.0.0-20241107155230-d37bb9f7e380 h1:EstDpct2ypQv500NPRQk92YBk9ZO0baDd94mna8o6w0= github.com/openshift/api v0.0.0-20241107155230-d37bb9f7e380/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= +github.com/openshift/api v0.0.0-20241120064718-caf97963ed30 h1:LrNXjO675I1FvPYE4P3UOFNlC0X37iKUUhgwk+huYnc= +github.com/openshift/api v0.0.0-20241120064718-caf97963ed30/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/interop/github.com/golang/protobuf/go.mod b/interop/github.com/golang/protobuf/go.mod index 76e71745..5ff59899 100644 --- a/interop/github.com/golang/protobuf/go.mod +++ b/interop/github.com/golang/protobuf/go.mod @@ -1,5 +1,5 @@ module github.com/golang/protobuf -go 1.23.2 +go 1.23.3 require google.golang.org/protobuf v1.35.1 diff --git a/src/apm/dotnet_test.go b/src/apm/dotnet_test.go index 77e8a6d1..b7c3f715 100644 --- a/src/apm/dotnet_test.go +++ b/src/apm/dotnet_test.go @@ -8,8 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/newrelic/k8s-agents-operator/src/api/v1alpha2" + "github.com/newrelic/k8s-agents-operator/src/internal/version" ) func TestDotnetInjector_Language(t *testing.T) { @@ -64,28 +66,33 @@ func TestDotnetInjector_Inject(t *testing.T) { pod: corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{ {Name: "test"}, }}}, - expectedPod: corev1.Pod{Spec: corev1.PodSpec{ - Containers: []corev1.Container{{ - Name: "test", - Env: []corev1.EnvVar{ - {Name: "CORECLR_ENABLE_PROFILING", Value: "1"}, - {Name: "CORECLR_PROFILER", Value: "{36032161-FFC0-4B61-B559-F6C5D41BAE5A}"}, - {Name: "CORECLR_PROFILER_PATH", Value: "/newrelic-instrumentation/libNewRelicProfiler.so"}, - {Name: "CORECLR_NEWRELIC_HOME", Value: "/newrelic-instrumentation"}, - {Name: "NEW_RELIC_APP_NAME", Value: "test"}, - {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, - {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, - {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, - }, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + expectedPod: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "CORECLR_ENABLE_PROFILING", Value: "1"}, + {Name: "CORECLR_PROFILER", Value: "{36032161-FFC0-4B61-B559-F6C5D41BAE5A}"}, + {Name: "CORECLR_PROFILER_PATH", Value: "/newrelic-instrumentation/libNewRelicProfiler.so"}, + {Name: "CORECLR_NEWRELIC_HOME", Value: "/newrelic-instrumentation"}, + {Name: "NEW_RELIC_APP_NAME", Value: "test"}, + {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, + {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, + {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, + }, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + InitContainers: []corev1.Container{{ + Name: "newrelic-instrumentation-dotnet", + Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"}, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, }}, - InitContainers: []corev1.Container{{ - Name: "newrelic-instrumentation-dotnet", - Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"}, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, - }}, - Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, - }}, inst: v1alpha2.Instrumentation{Spec: v1alpha2.InstrumentationSpec{Agent: v1alpha2.Agent{Language: "dotnet"}, LicenseKeySecret: "newrelic-key-secret"}}, }, } diff --git a/src/apm/helper.go b/src/apm/helper.go index ef0c5991..4a85b24d 100644 --- a/src/apm/helper.go +++ b/src/apm/helper.go @@ -36,6 +36,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/newrelic/k8s-agents-operator/src/api/v1alpha2" + "github.com/newrelic/k8s-agents-operator/src/internal/version" ) const LicenseKey = "new_relic_license_key" @@ -46,10 +47,11 @@ const ( ) const ( - EnvNewRelicAppName = "NEW_RELIC_APP_NAME" - EnvNewRelicK8sOperatorEnabled = "NEW_RELIC_K8S_OPERATOR_ENABLED" - EnvNewRelicLabels = "NEW_RELIC_LABELS" - EnvNewRelicLicenseKey = "NEW_RELIC_LICENSE_KEY" + EnvNewRelicAppName = "NEW_RELIC_APP_NAME" + EnvNewRelicK8sOperatorEnabled = "NEW_RELIC_K8S_OPERATOR_ENABLED" + EnvNewRelicLabels = "NEW_RELIC_LABELS" + EnvNewRelicLicenseKey = "NEW_RELIC_LICENSE_KEY" + DescK8sAgentOperatorVersionLabelName = "newrelic-k8s-agents-operator-version" ) var ErrInjectorAlreadyRegistered = errors.New("injector already registered in registry") @@ -252,6 +254,11 @@ func (i *baseInjector) injectNewrelicEnvConfig(ctx context.Context, resource v1a Name: EnvNewRelicLabels, Value: "operator:auto-injection", }) + } else { + customLabel := container.Env[idx].Value + customLabel += ";operator:auto-injection" + container.Env[idx].Value = customLabel + } if idx := getIndexOfEnv(container.Env, EnvNewRelicK8sOperatorEnabled); idx == -1 { container.Env = append(container.Env, corev1.EnvVar{ @@ -259,6 +266,8 @@ func (i *baseInjector) injectNewrelicEnvConfig(ctx context.Context, resource v1a Value: "true", }) } + // Also apply specific pod labels indicating that operator is being attached and it's version + ApplyLabel(&pod, DescK8sAgentOperatorVersionLabelName, version.Get().Operator) return pod } @@ -390,3 +399,12 @@ func createServiceInstanceId(namespaceName, podName, containerName string) strin } return serviceInstanceId } + +func ApplyLabel(pod *corev1.Pod, key, val string) *corev1.Pod { + labels := pod.ObjectMeta.GetLabels() + if labels == nil { + pod.ObjectMeta.Labels = make(map[string]string) + } + pod.ObjectMeta.Labels[key] = val + return pod +} diff --git a/src/apm/helper_test.go b/src/apm/helper_test.go index ee76c51d..dfe20f72 100644 --- a/src/apm/helper_test.go +++ b/src/apm/helper_test.go @@ -1,6 +1,13 @@ package apm -import "testing" +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) func TestBaseInjector_ConfigureClient(t *testing.T) { @@ -21,3 +28,46 @@ func TestInjectorRegistery_MustRegister(t *testing.T) { func TestInjectors_Names(t *testing.T) { } + +func TestApplyLabel(t *testing.T) { + tests := []struct { + name string + pod *corev1.Pod + expectedPod *corev1.Pod + expectedErrStr string + }{ + { + name: "a container with labels added", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "NEW_RELIC_LABELS", Value: "app:java-injected"}, + }}}}}, + + expectedPod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "foo": "bar"}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "NEW_RELIC_LABELS", Value: "app:java-injected"}, + }, + }}, + }}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + actualPod := ApplyLabel(test.pod, "foo", "bar") + + if diff := cmp.Diff(test.expectedPod, actualPod); diff != "" { + assert.Fail(t, diff) + } + }) + } +} diff --git a/src/apm/java_test.go b/src/apm/java_test.go index 913ce9d4..b711d104 100644 --- a/src/apm/java_test.go +++ b/src/apm/java_test.go @@ -8,8 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/newrelic/k8s-agents-operator/src/api/v1alpha2" + "github.com/newrelic/k8s-agents-operator/src/internal/version" ) func TestJavaInjector_Language(t *testing.T) { @@ -26,6 +28,7 @@ func TestJavaInjector_Inject(t *testing.T) { expectedPod corev1.Pod expectedErrStr string }{ + { name: "nothing", }, @@ -64,25 +67,66 @@ func TestJavaInjector_Inject(t *testing.T) { pod: corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{ {Name: "test"}, }}}, - expectedPod: corev1.Pod{Spec: corev1.PodSpec{ - Containers: []corev1.Container{{ - Name: "test", - Env: []corev1.EnvVar{ - {Name: "JAVA_TOOL_OPTIONS", Value: " -javaagent:/newrelic-instrumentation/newrelic-agent.jar"}, - {Name: "NEW_RELIC_APP_NAME", Value: "test"}, - {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, - {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, - {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, - }, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + expectedPod: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "JAVA_TOOL_OPTIONS", Value: " -javaagent:/newrelic-instrumentation/newrelic-agent.jar"}, + {Name: "NEW_RELIC_APP_NAME", Value: "test"}, + {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, + {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, + {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, + }, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + InitContainers: []corev1.Container{{ + Name: "newrelic-instrumentation-java", + Command: []string{"cp", "/newrelic-agent.jar", "/newrelic-instrumentation/newrelic-agent.jar"}, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, }}, - InitContainers: []corev1.Container{{ - Name: "newrelic-instrumentation-java", - Command: []string{"cp", "/newrelic-agent.jar", "/newrelic-instrumentation/newrelic-agent.jar"}, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + inst: v1alpha2.Instrumentation{Spec: v1alpha2.InstrumentationSpec{Agent: v1alpha2.Agent{Language: "java"}, LicenseKeySecret: "newrelic-key-secret"}}, + }, + { + name: "a container, instrumentation with added new relic labels", + pod: corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "NEW_RELIC_LABELS", Value: "app:java-injected"}, + }}}}}, + + expectedPod: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "NEW_RELIC_LABELS", Value: "app:java-injected;operator:auto-injection"}, + {Name: "JAVA_TOOL_OPTIONS", Value: " -javaagent:/newrelic-instrumentation/newrelic-agent.jar"}, + {Name: "NEW_RELIC_APP_NAME", Value: "test"}, + {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, + {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, + }, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + InitContainers: []corev1.Container{{ + Name: "newrelic-instrumentation-java", + Command: []string{"cp", "/newrelic-agent.jar", "/newrelic-instrumentation/newrelic-agent.jar"}, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, }}, - Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, - }}, inst: v1alpha2.Instrumentation{Spec: v1alpha2.InstrumentationSpec{Agent: v1alpha2.Agent{Language: "java"}, LicenseKeySecret: "newrelic-key-secret"}}, }, } diff --git a/src/apm/nodejs_test.go b/src/apm/nodejs_test.go index 2fe3ba02..ae21d83c 100644 --- a/src/apm/nodejs_test.go +++ b/src/apm/nodejs_test.go @@ -8,8 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/newrelic/k8s-agents-operator/src/api/v1alpha2" + "github.com/newrelic/k8s-agents-operator/src/internal/version" ) func TestNodejsInjector_Language(t *testing.T) { @@ -64,25 +66,30 @@ func TestNodejsInjector_Inject(t *testing.T) { pod: corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{ {Name: "test"}, }}}, - expectedPod: corev1.Pod{Spec: corev1.PodSpec{ - Containers: []corev1.Container{{ - Name: "test", - Env: []corev1.EnvVar{ - {Name: "NODE_OPTIONS", Value: " --require /newrelic-instrumentation/newrelicinstrumentation.js"}, - {Name: "NEW_RELIC_APP_NAME", Value: "test"}, - {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, - {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, - {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, - }, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + expectedPod: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "NODE_OPTIONS", Value: " --require /newrelic-instrumentation/newrelicinstrumentation.js"}, + {Name: "NEW_RELIC_APP_NAME", Value: "test"}, + {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, + {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, + {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, + }, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + InitContainers: []corev1.Container{{ + Name: "newrelic-instrumentation-nodejs", + Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"}, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, }}, - InitContainers: []corev1.Container{{ - Name: "newrelic-instrumentation-nodejs", - Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"}, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, - }}, - Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, - }}, inst: v1alpha2.Instrumentation{Spec: v1alpha2.InstrumentationSpec{Agent: v1alpha2.Agent{Language: "nodejs"}, LicenseKeySecret: "newrelic-key-secret"}}, }, } diff --git a/src/apm/php_test.go b/src/apm/php_test.go index 01a81935..9643467f 100644 --- a/src/apm/php_test.go +++ b/src/apm/php_test.go @@ -11,6 +11,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/newrelic/k8s-agents-operator/src/api/v1alpha2" + "github.com/newrelic/k8s-agents-operator/src/internal/version" ) func TestPhpInjector_Language(t *testing.T) { @@ -74,7 +75,11 @@ func TestPhpInjector_Inject(t *testing.T) { }}, }, expectedPod: corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"instrumentation.newrelic.com/php-version": "8.3"}}, + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{"instrumentation.newrelic.com/php-version": "8.3"}, + Labels: map[string]string{ + DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, Spec: corev1.PodSpec{ Containers: []corev1.Container{{ Name: "test", diff --git a/src/apm/python_test.go b/src/apm/python_test.go index 9fc1c138..b4b52fed 100644 --- a/src/apm/python_test.go +++ b/src/apm/python_test.go @@ -8,8 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/newrelic/k8s-agents-operator/src/api/v1alpha2" + "github.com/newrelic/k8s-agents-operator/src/internal/version" ) func TestPythonInjector_Language(t *testing.T) { @@ -64,25 +66,29 @@ func TestPythonInjector_Inject(t *testing.T) { pod: corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{ {Name: "test"}, }}}, - expectedPod: corev1.Pod{Spec: corev1.PodSpec{ - Containers: []corev1.Container{{ - Name: "test", - Env: []corev1.EnvVar{ - {Name: "PYTHONPATH", Value: "/newrelic-instrumentation"}, - {Name: "NEW_RELIC_APP_NAME", Value: "test"}, - {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, - {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, - {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, - }, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + expectedPod: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "PYTHONPATH", Value: "/newrelic-instrumentation"}, + {Name: "NEW_RELIC_APP_NAME", Value: "test"}, + {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, + {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, + {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, + }, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + InitContainers: []corev1.Container{{ + Name: "newrelic-instrumentation-python", + Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"}, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, }}, - InitContainers: []corev1.Container{{ - Name: "newrelic-instrumentation-python", - Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"}, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, - }}, - Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, - }}, inst: v1alpha2.Instrumentation{Spec: v1alpha2.InstrumentationSpec{Agent: v1alpha2.Agent{Language: "python"}, LicenseKeySecret: "newrelic-key-secret"}}, }, } diff --git a/src/apm/ruby_test.go b/src/apm/ruby_test.go index 14d2459f..3831f2ca 100644 --- a/src/apm/ruby_test.go +++ b/src/apm/ruby_test.go @@ -8,8 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/newrelic/k8s-agents-operator/src/api/v1alpha2" + "github.com/newrelic/k8s-agents-operator/src/internal/version" ) func TestRubyInjector_Language(t *testing.T) { @@ -64,25 +66,29 @@ func TestRubyInjector_Inject(t *testing.T) { pod: corev1.Pod{Spec: corev1.PodSpec{Containers: []corev1.Container{ {Name: "test"}, }}}, - expectedPod: corev1.Pod{Spec: corev1.PodSpec{ - Containers: []corev1.Container{{ - Name: "test", - Env: []corev1.EnvVar{ - {Name: "RUBYOPT", Value: "-r /newrelic-instrumentation/lib/boot/strap"}, - {Name: "NEW_RELIC_APP_NAME", Value: "test"}, - {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, - {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, - {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, - }, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + expectedPod: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "test", + Env: []corev1.EnvVar{ + {Name: "RUBYOPT", Value: "-r /newrelic-instrumentation/lib/boot/strap"}, + {Name: "NEW_RELIC_APP_NAME", Value: "test"}, + {Name: "NEW_RELIC_LABELS", Value: "operator:auto-injection"}, + {Name: "NEW_RELIC_K8S_OPERATOR_ENABLED", Value: "true"}, + {Name: "NEW_RELIC_LICENSE_KEY", ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "newrelic-key-secret"}, Key: "new_relic_license_key", Optional: &vtrue}}}, + }, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + InitContainers: []corev1.Container{{ + Name: "newrelic-instrumentation-ruby", + Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"}, + VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, + }}, + Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, }}, - InitContainers: []corev1.Container{{ - Name: "newrelic-instrumentation-ruby", - Command: []string{"cp", "-a", "/instrumentation/.", "/newrelic-instrumentation/"}, - VolumeMounts: []corev1.VolumeMount{{Name: "newrelic-instrumentation", MountPath: "/newrelic-instrumentation"}}, - }}, - Volumes: []corev1.Volume{{Name: "newrelic-instrumentation", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}}, - }}, inst: v1alpha2.Instrumentation{Spec: v1alpha2.InstrumentationSpec{Agent: v1alpha2.Agent{Language: "ruby"}, LicenseKeySecret: "newrelic-key-secret"}}, }, } diff --git a/src/internal/webhookhandler/webhookhandler_suite_test.go b/src/internal/webhookhandler/webhookhandler_suite_test.go index da9345dc..d3f30feb 100644 --- a/src/internal/webhookhandler/webhookhandler_suite_test.go +++ b/src/internal/webhookhandler/webhookhandler_suite_test.go @@ -20,10 +20,7 @@ import ( "context" "crypto/tls" "fmt" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" "io" - apierrors "k8s.io/apimachinery/pkg/api/errors" "net" "os" "path/filepath" @@ -32,6 +29,10 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + apierrors "k8s.io/apimachinery/pkg/api/errors" + admissionv1 "k8s.io/api/admission/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -292,7 +293,10 @@ func TestPodMutationHandler_Handle(t *testing.T) { }, }, expectedPod: corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "alpine1", Namespace: "default", Labels: map[string]string{"inject": "python"}}, + ObjectMeta: metav1.ObjectMeta{Name: "alpine1", Namespace: "default", Labels: map[string]string{ + "inject": "python", + apm.DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, Spec: corev1.PodSpec{ InitContainers: []corev1.Container{ { @@ -380,7 +384,10 @@ func TestPodMutationHandler_Handle(t *testing.T) { }, }, expectedPod: corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "alpine2", Namespace: "default", Labels: map[string]string{"inject": "php"}}, + ObjectMeta: metav1.ObjectMeta{Name: "alpine2", Namespace: "default", Labels: map[string]string{ + "inject": "php", + apm.DescK8sAgentOperatorVersionLabelName: version.Get().Operator}, + }, Spec: corev1.PodSpec{ InitContainers: []corev1.Container{ {