From d91b1162c12f07a7caf660004465b1006eccdf2f Mon Sep 17 00:00:00 2001 From: Fredrik Gundersen Date: Tue, 25 Feb 2025 15:53:59 +0100 Subject: [PATCH] INSTA-13149: Make open telemetry ports and enablement more configurable --- api/v1/inline_types.go | 50 +- api/v1/inline_types_test.go | 455 +++++++++--------- api/v1/instanaagent_types.go | 7 +- api/v1/zz_generated.deepcopy.go | 37 +- e2e/agent_test_api.go | 10 +- .../builders/agent/daemonset/daemonset.go | 34 +- .../agent/daemonset/daemonset_test.go | 44 +- .../headless-service/headless-service.go | 31 +- .../headless-service/headless-service_test.go | 32 +- .../object/builders/agent/secrets/config.go | 4 +- .../builders/agent/secrets/config_test.go | 4 +- .../object/builders/agent/service/service.go | 23 +- .../builders/agent/service/service_test.go | 38 +- .../object/builders/common/env/env_builder.go | 22 + .../object/builders/common/ports/helpers.go | 40 -- .../common/ports/instana_agent_port.go | 67 --- .../common/ports/instana_agent_port_config.go | 55 +++ .../builders/common/ports/ports_builder.go | 87 ++-- .../common/ports/ports_builder_test.go | 211 ++++++++ .../builders/common/ports/ports_test.go | 259 ---------- .../k8s-sensor/deployment/deployment.go | 7 +- 21 files changed, 667 insertions(+), 850 deletions(-) delete mode 100644 pkg/k8s/object/builders/common/ports/helpers.go delete mode 100644 pkg/k8s/object/builders/common/ports/instana_agent_port.go create mode 100644 pkg/k8s/object/builders/common/ports/instana_agent_port_config.go create mode 100644 pkg/k8s/object/builders/common/ports/ports_builder_test.go delete mode 100644 pkg/k8s/object/builders/common/ports/ports_test.go diff --git a/api/v1/inline_types.go b/api/v1/inline_types.go index 8eb53405..87176ea2 100644 --- a/api/v1/inline_types.go +++ b/api/v1/inline_types.go @@ -1,7 +1,7 @@ /* - * (c) Copyright IBM Corp. 2021 - * (c) Copyright Instana Inc. 2021 - */ + (c) Copyright IBM Corp. 2021,2025 +*/ + package v1 import ( @@ -356,44 +356,26 @@ type KubernetesDeploymentSpec struct { } type OpenTelemetry struct { - // Deprecated setting for backwards compatibility + // Deprecated setting for backwards compatibility. Specify whether Open telemetry is enabled (default is true). + // +kubebuilder:validation:Optional Enabled `json:",inline" yaml:",inline"` + // Specify whether GRPC is enabled (default is true). // +kubebuilder:validation:Optional - GRPC *Enabled `json:"grpc,omitempty" yaml:"grpc,omitempty"` + GRPC OpenTelemetryPortConfig `json:"grpc,omitempty" yaml:"grpc,omitempty"` + // Specify whether HTTP is enabled (default is true). // +kubebuilder:validation:Optional - HTTP *Enabled `json:"http,omitempty" yaml:"http,omitempty"` + HTTP OpenTelemetryPortConfig `json:"http,omitempty" yaml:"http,omitempty"` } -func (otlp OpenTelemetry) GrpcIsEnabled() bool { - // explicit opt-out or opt-in via new setting - if otlp.GRPC != nil && otlp.GRPC.Enabled != nil { - return *otlp.GRPC.Enabled - } - // explicit opt-out via legacy setting - if otlp.Enabled.Enabled != nil && !*otlp.Enabled.Enabled { - return false - } - // enabled by default - return true -} - -func (otlp OpenTelemetry) HttpIsEnabled() bool { - // explicit opt-out or opt-in via new setting - if otlp.HTTP != nil && otlp.HTTP.Enabled != nil { - return *otlp.HTTP.Enabled - } - // explicit opt-out via legacy setting - if otlp.Enabled.Enabled != nil && !*otlp.Enabled.Enabled { - return false - } - // enabled by default - return true -} - -func (otlp OpenTelemetry) IsEnabled() bool { - return otlp.GrpcIsEnabled() || otlp.HttpIsEnabled() +type OpenTelemetryPortConfig struct { + // Explicitly enable + // +kubebuilder:validation:Optional + Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + // Specify the port + // +kubebuilder:validation:Optional + Port *int32 `json:"port,omitempty" yaml:"port,omitempty"` } type Zone struct { diff --git a/api/v1/inline_types_test.go b/api/v1/inline_types_test.go index c39be37d..4ab323cb 100644 --- a/api/v1/inline_types_test.go +++ b/api/v1/inline_types_test.go @@ -1,18 +1,5 @@ /* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +(c) Copyright IBM Corp. 2024,2025 */ package v1 @@ -80,231 +67,231 @@ func TestImageSpec_Image(t *testing.T) { } } -func TestOpenTelemetry_GrpcIsEnabled(t *testing.T) { - enabled := true - disabled := false +// func TestOpenTelemetry_GrpcIsEnabled(t *testing.T) { +// enabled := true +// disabled := false - for _, test := range []struct { - name string - openTelemetrySettings OpenTelemetry - expected bool - }{ - { - name: "Enable by default, if nothing is defined", - openTelemetrySettings: OpenTelemetry{}, - expected: true, - }, - { - name: "Legacy setting enabled", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "Legacy setting disabled", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New GRPC setting enabled, no legacy setting", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "New GRPC setting disabled, no legacy setting", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "Explicit opt-in with all settings", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "Explicitly opt-out with all settings", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, GRPC: &Enabled{Enabled: &disabled}, HTTP: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New setting opt-out, legacy setting opt-in -> new should win", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New setting opt-in, legacy setting opt-out -> new should win", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, GRPC: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "New setting opt-in GRPC=true is not interfering with HTTP=true setting", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "New setting opt-in GRPC=false is not interfering with HTTP=true setting", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &disabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: false, - }, - { - name: "New setting opt-in GRPC=true is not interfering with HTTP=false setting", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &disabled}}, - expected: true, - }, - } { - t.Run(test.name, func(t *testing.T) { - assertions := require.New(t) - assertions.Equal(test.expected, test.openTelemetrySettings.GrpcIsEnabled(), test.name) - }) - } -} +// for _, test := range []struct { +// name string +// openTelemetrySettings OpenTelemetry +// expected bool +// }{ +// { +// name: "Enable by default, if nothing is defined", +// openTelemetrySettings: OpenTelemetry{}, +// expected: true, +// }, +// { +// name: "Legacy setting enabled", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "Legacy setting disabled", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New GRPC setting enabled, no legacy setting", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "New GRPC setting disabled, no legacy setting", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "Explicit opt-in with all settings", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "Explicitly opt-out with all settings", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New setting opt-out, legacy setting opt-in -> new should win", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New setting opt-in, legacy setting opt-out -> new should win", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "New setting opt-in GRPC=true is not interfering with HTTP=true setting", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "New setting opt-in GRPC=false is not interfering with HTTP=true setting", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: false, +// }, +// { +// name: "New setting opt-in GRPC=true is not interfering with HTTP=false setting", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: true, +// }, +// } { +// t.Run(test.name, func(t *testing.T) { +// assertions := require.New(t) +// assertions.Equal(test.expected, test.openTelemetrySettings.GRPC.Enabled, test.name) +// }) +// } +// } -func TestOpenTelemetry_HttpIsEnabled(t *testing.T) { - enabled := true - disabled := false +// func TestOpenTelemetry_HttpIsEnabled(t *testing.T) { +// enabled := true +// disabled := false - for _, test := range []struct { - name string - openTelemetrySettings OpenTelemetry - expected bool - }{ - { - name: "Enable by default, if nothing is defined", - openTelemetrySettings: OpenTelemetry{}, - expected: true, - }, - { - name: "Legacy setting enabled", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "Legacy setting disabled", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New HTTP setting enabled, no legacy setting", - openTelemetrySettings: OpenTelemetry{HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "New HTTP setting disabled, no legacy setting", - openTelemetrySettings: OpenTelemetry{HTTP: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "Explicit opt-in with all settings", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "Explicitly opt-out with all settings", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, GRPC: &Enabled{Enabled: &disabled}, HTTP: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New setting opt-out, legacy setting opt-in -> new should win", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New setting opt-in, legacy setting opt-out -> new should win", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "New setting opt-in HTTP=true is not interfering with GRPC=true setting", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "New setting opt-in HTTP=false is not interfering with GRPC=true setting", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New setting opt-in HTTP=true is not interfering with GRPC=false setting", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &disabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - } { - t.Run(test.name, func(t *testing.T) { - assertions := require.New(t) - assertions.Equal(test.expected, test.openTelemetrySettings.HttpIsEnabled(), test.name) - }) - } -} +// for _, test := range []struct { +// name string +// openTelemetrySettings OpenTelemetry +// expected bool +// }{ +// { +// name: "Enable by default, if nothing is defined", +// openTelemetrySettings: OpenTelemetry{}, +// expected: true, +// }, +// { +// name: "Legacy setting enabled", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "Legacy setting disabled", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New HTTP setting enabled, no legacy setting", +// openTelemetrySettings: OpenTelemetry{HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "New HTTP setting disabled, no legacy setting", +// openTelemetrySettings: OpenTelemetry{HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "Explicit opt-in with all settings", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "Explicitly opt-out with all settings", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New setting opt-out, legacy setting opt-in -> new should win", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New setting opt-in, legacy setting opt-out -> new should win", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "New setting opt-in HTTP=true is not interfering with GRPC=true setting", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "New setting opt-in HTTP=false is not interfering with GRPC=true setting", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New setting opt-in HTTP=true is not interfering with GRPC=false setting", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// } { +// t.Run(test.name, func(t *testing.T) { +// assertions := require.New(t) +// assertions.Equal(test.expected, test.openTelemetrySettings.HttpIsEnabled(), test.name) +// }) +// } +// } -func TestOpenTelemetry_IsEnabled(t *testing.T) { - enabled := true - disabled := false +// func TestOpenTelemetry_IsEnabled(t *testing.T) { +// enabled := true +// disabled := false - for _, test := range []struct { - name string - openTelemetrySettings OpenTelemetry - expected bool - }{ - { - name: "Enable by default, if nothing is defined", - openTelemetrySettings: OpenTelemetry{}, - expected: true, - }, - { - name: "Legacy setting enabled", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "Legacy setting disabled", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New HTTP setting enabled, no legacy setting", - openTelemetrySettings: OpenTelemetry{HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "New HTTP setting disabled, no legacy setting, fallback to GPRC enabled -> overall enabled", - openTelemetrySettings: OpenTelemetry{HTTP: &Enabled{Enabled: &disabled}}, - expected: true, - }, - { - name: "New GRPC setting disabled, no legacy setting, fallback to HTTP enabled -> overall enabled", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &disabled}}, - expected: true, - }, - { - name: "Explicit opt-in with all settings", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "Explicitly opt-out with all settings", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, GRPC: &Enabled{Enabled: &disabled}, HTTP: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New settings opt-out, legacy setting opt-in -> new should win", - openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &Enabled{Enabled: &disabled}, HTTP: &Enabled{Enabled: &disabled}}, - expected: false, - }, - { - name: "New settings explicit opt-in for HTTP and opt-out for GRPC -> overall true", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &disabled}, HTTP: &Enabled{Enabled: &enabled}}, - expected: true, - }, - { - name: "New settings explicit opt-out for HTTP and opt-in for GRPC -> overall true", - openTelemetrySettings: OpenTelemetry{GRPC: &Enabled{Enabled: &enabled}, HTTP: &Enabled{Enabled: &disabled}}, - expected: true, - }, - } { - t.Run(test.name, func(t *testing.T) { - assertions := require.New(t) - assertions.Equal(test.expected, test.openTelemetrySettings.IsEnabled(), test.name) - }) - } -} +// for _, test := range []struct { +// name string +// openTelemetrySettings OpenTelemetry +// expected bool +// }{ +// { +// name: "Enable by default, if nothing is defined", +// openTelemetrySettings: OpenTelemetry{}, +// expected: true, +// }, +// { +// name: "Legacy setting enabled", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "Legacy setting disabled", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New HTTP setting enabled, no legacy setting", +// openTelemetrySettings: OpenTelemetry{HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "New HTTP setting disabled, no legacy setting, fallback to GPRC enabled -> overall enabled", +// openTelemetrySettings: OpenTelemetry{HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: true, +// }, +// { +// name: "New GRPC setting disabled, no legacy setting, fallback to HTTP enabled -> overall enabled", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: true, +// }, +// { +// name: "Explicit opt-in with all settings", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "Explicitly opt-out with all settings", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &disabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New settings opt-out, legacy setting opt-in -> new should win", +// openTelemetrySettings: OpenTelemetry{Enabled: Enabled{Enabled: &enabled}, GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: false, +// }, +// { +// name: "New settings explicit opt-in for HTTP and opt-out for GRPC -> overall true", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &disabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &enabled}}, +// expected: true, +// }, +// { +// name: "New settings explicit opt-out for HTTP and opt-in for GRPC -> overall true", +// openTelemetrySettings: OpenTelemetry{GRPC: &OpenTelemetryPortConfig{Enabled: &enabled}, HTTP: &OpenTelemetryPortConfig{Enabled: &disabled}}, +// expected: true, +// }, +// } { +// t.Run(test.name, func(t *testing.T) { +// assertions := require.New(t) +// assertions.Equal(test.expected, test.openTelemetrySettings.IsEnabled(), test.name) +// }) +// } +// } func TestDaemonSetBuilder_getResourceRequirements(t *testing.T) { metaAssertions := require.New(t) diff --git a/api/v1/instanaagent_types.go b/api/v1/instanaagent_types.go index efd2502f..6617b192 100644 --- a/api/v1/instanaagent_types.go +++ b/api/v1/instanaagent_types.go @@ -1,6 +1,5 @@ /* - * (c) Copyright IBM Corp. 2021 - * (c) Copyright Instana Inc. 2021 + * (c) Copyright IBM Corp. 2021,2025 */ package v1 @@ -173,6 +172,10 @@ func (in *InstanaAgent) Default() { optional.ValueOrDefault(&in.Spec.K8sSensor.ImageSpec.Tag, "latest") optional.ValueOrDefault(&in.Spec.K8sSensor.ImageSpec.PullPolicy, corev1.PullAlways) optional.ValueOrDefault(&in.Spec.K8sSensor.DeploymentSpec.Replicas, 3) + + optional.ValueOrDefault(&in.Spec.OpenTelemetry.Enabled.Enabled, pointer.To(true)) + optional.ValueOrDefault(&in.Spec.OpenTelemetry.GRPC.Enabled, in.Spec.OpenTelemetry.Enabled.Enabled) + optional.ValueOrDefault(&in.Spec.OpenTelemetry.HTTP.Enabled, in.Spec.OpenTelemetry.Enabled.Enabled) } // +kubebuilder:object:root=true diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 514ed03d..2d62d404 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -469,16 +469,8 @@ func (in *Name) DeepCopy() *Name { func (in *OpenTelemetry) DeepCopyInto(out *OpenTelemetry) { *out = *in in.Enabled.DeepCopyInto(&out.Enabled) - if in.GRPC != nil { - in, out := &in.GRPC, &out.GRPC - *out = new(Enabled) - (*in).DeepCopyInto(*out) - } - if in.HTTP != nil { - in, out := &in.HTTP, &out.HTTP - *out = new(Enabled) - (*in).DeepCopyInto(*out) - } + in.GRPC.DeepCopyInto(&out.GRPC) + in.HTTP.DeepCopyInto(&out.HTTP) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenTelemetry. @@ -491,6 +483,31 @@ func (in *OpenTelemetry) DeepCopy() *OpenTelemetry { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenTelemetryPortConfig) DeepCopyInto(out *OpenTelemetryPortConfig) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenTelemetryPortConfig. +func (in *OpenTelemetryPortConfig) DeepCopy() *OpenTelemetryPortConfig { + if in == nil { + return nil + } + out := new(OpenTelemetryPortConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSecurityPolicySpec) DeepCopyInto(out *PodSecurityPolicySpec) { *out = *in diff --git a/e2e/agent_test_api.go b/e2e/agent_test_api.go index 8a92b64c..85d74f49 100644 --- a/e2e/agent_test_api.go +++ b/e2e/agent_test_api.go @@ -1,6 +1,5 @@ /* - * (c) Copyright IBM Corp. 2024 - * (c) Copyright Instana Inc. 2024 + * (c) Copyright IBM Corp. 2024,2025 */ package e2e @@ -513,7 +512,7 @@ func ValidateAgentMultiBackendConfiguration() e2etypes.StepFunc { // Helper to produce test structs func NewAgentCr(t *testing.T) v1.InstanaAgent { - boolTrue := true + enabled := true return v1.InstanaAgent{ ObjectMeta: metav1.ObjectMeta{ @@ -532,8 +531,9 @@ func NewAgentCr(t *testing.T) v1.InstanaAgent { EndpointPort: strconv.Itoa(InstanaTestCfg.InstanaBackend.EndpointPort), }, OpenTelemetry: v1.OpenTelemetry{ - GRPC: &v1.Enabled{Enabled: &boolTrue}, - HTTP: &v1.Enabled{Enabled: &boolTrue}, + Enabled: v1.Enabled{Enabled: &enabled}, + GRPC: v1.OpenTelemetryPortConfig{Enabled: &enabled}, + HTTP: v1.OpenTelemetryPortConfig{Enabled: &enabled}, }, }, } diff --git a/pkg/k8s/object/builders/agent/daemonset/daemonset.go b/pkg/k8s/object/builders/agent/daemonset/daemonset.go index d78755b3..69cc4dfd 100644 --- a/pkg/k8s/object/builders/agent/daemonset/daemonset.go +++ b/pkg/k8s/object/builders/agent/daemonset/daemonset.go @@ -1,18 +1,5 @@ /* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +(c) Copyright IBM Corp. 2024,2025 */ package daemonset @@ -51,11 +38,11 @@ type daemonSetBuilder struct { transformations.PodSelectorLabelGenerator hash.JsonHasher helpers.Helpers - ports.PortsBuilder env.EnvBuilder volume.VolumeBuilder - zone *instanav1.Zone + portsBuilder ports.PortsBuilder + zone *instanav1.Zone } func (d *daemonSetBuilder) ComponentName() string { @@ -102,15 +89,6 @@ func (d *daemonSetBuilder) getEnvVars() []corev1.EnvVar { ) } -func (d *daemonSetBuilder) getContainerPorts() []corev1.ContainerPort { - return d.GetContainerPorts( - ports.AgentAPIsPort, - ports.OpenTelemetryLegacyPort, - ports.OpenTelemetryGRPCPort, - ports.OpenTelemetryHTTPPort, - ) -} - func (d *daemonSetBuilder) getVolumes() ([]corev1.Volume, []corev1.VolumeMount) { return d.VolumeBuilder.Build( volume.DevVolume, @@ -215,7 +193,7 @@ func (d *daemonSetBuilder) build() *appsv1.DaemonSet { HTTPGet: &corev1.HTTPGetAction{ Host: "127.0.0.1", Path: "/status", - Port: intstr.FromString(string(ports.AgentAPIsPort)), + Port: intstr.FromInt32(ports.InstanaAgentAPIPortConfig.Port), }, }, InitialDelaySeconds: 600, @@ -224,7 +202,7 @@ func (d *daemonSetBuilder) build() *appsv1.DaemonSet { FailureThreshold: 3, }, Resources: d.Spec.Agent.Pod.ResourceRequirements.GetOrDefault(), - Ports: d.getContainerPorts(), + Ports: d.portsBuilder.GetContainerPorts(), }, }, Tolerations: d.getTolerations(), @@ -278,7 +256,7 @@ func NewDaemonSetBuilderWithZoneInfo( PodSelectorLabelGenerator: transformations.PodSelectorLabelsWithZoneInfo(agent, componentName, zone), JsonHasher: hash.NewJsonHasher(), Helpers: helpers.NewHelpers(agent), - PortsBuilder: ports.NewPortsBuilder(agent), + portsBuilder: ports.NewPortsBuilder(agent.Spec.OpenTelemetry), EnvBuilder: env.NewEnvBuilder(agent, zone), VolumeBuilder: volume.NewVolumeBuilder(agent, isOpenshift), zone: zone, diff --git a/pkg/k8s/object/builders/agent/daemonset/daemonset_test.go b/pkg/k8s/object/builders/agent/daemonset/daemonset_test.go index e381710e..9a5241f2 100644 --- a/pkg/k8s/object/builders/agent/daemonset/daemonset_test.go +++ b/pkg/k8s/object/builders/agent/daemonset/daemonset_test.go @@ -1,18 +1,5 @@ /* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +(c) Copyright IBM Corp. 2024,2025 */ package daemonset @@ -31,7 +18,6 @@ import ( instanav1 "github.com/instana/instana-agent-operator/api/v1" "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/constants" "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/env" - "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/ports" "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/volume" "github.com/instana/instana-agent-operator/pkg/k8s/object/transformations" ) @@ -180,34 +166,6 @@ func TestDaemonSetBuilder_getEnvVars(t *testing.T) { assertions.Equal(expected, actual) } -func TestDaemonSetBuilder_getContainerPorts(t *testing.T) { - assertions := require.New(t) - ctrl := gomock.NewController(t) - - expected := []corev1.ContainerPort{ - { - Name: "something", - ContainerPort: 12345, - }, - } - - portsBuilder := mocks.NewMockPortsBuilder(ctrl) - portsBuilder.EXPECT().GetContainerPorts( - ports.AgentAPIsPort, - ports.OpenTelemetryLegacyPort, - ports.OpenTelemetryGRPCPort, - ports.OpenTelemetryHTTPPort, - ).Return(expected) - - db := &daemonSetBuilder{ - PortsBuilder: portsBuilder, - } - - actual := db.getContainerPorts() - - assertions.Equal(expected, actual) -} - func TestDaemonSetBuilder_getVolumes(t *testing.T) { assertions := require.New(t) ctrl := gomock.NewController(t) diff --git a/pkg/k8s/object/builders/agent/headless-service/headless-service.go b/pkg/k8s/object/builders/agent/headless-service/headless-service.go index a43d58b1..666e994d 100644 --- a/pkg/k8s/object/builders/agent/headless-service/headless-service.go +++ b/pkg/k8s/object/builders/agent/headless-service/headless-service.go @@ -1,3 +1,7 @@ +/* +(c) Copyright IBM Corp. 2024,2025 +*/ + package headless_service import ( @@ -20,12 +24,20 @@ const ( type headlessServiceBuilder struct { *instanav1.InstanaAgent - helpers.Helpers transformations.PodSelectorLabelGenerator ports.PortsBuilder } +func NewHeadlessServiceBuilder(agent *instanav1.InstanaAgent) builder.ObjectBuilder { + return &headlessServiceBuilder{ + InstanaAgent: agent, + Helpers: helpers.NewHelpers(agent), + PodSelectorLabelGenerator: transformations.PodSelectorLabels(agent, componentName), + PortsBuilder: ports.NewPortsBuilder(agent.Spec.OpenTelemetry), + } +} + func (h *headlessServiceBuilder) Build() builder.OptionalObject { return optional.Of[client.Object]( &corev1.Service{ @@ -40,12 +52,7 @@ func (h *headlessServiceBuilder) Build() builder.OptionalObject { Spec: corev1.ServiceSpec{ ClusterIP: corev1.ClusterIPNone, Selector: h.GetPodSelectorLabels(), - Ports: h.GetServicePorts( - ports.AgentAPIsPort, - ports.OpenTelemetryLegacyPort, - ports.OpenTelemetryGRPCPort, - ports.OpenTelemetryHTTPPort, - ), + Ports: h.GetServicePorts(), }, }, ) @@ -58,13 +65,3 @@ func (h *headlessServiceBuilder) ComponentName() string { func (h *headlessServiceBuilder) IsNamespaced() bool { return true } - -func NewHeadlessServiceBuilder(agent *instanav1.InstanaAgent) builder.ObjectBuilder { - return &headlessServiceBuilder{ - InstanaAgent: agent, - - Helpers: helpers.NewHelpers(agent), - PodSelectorLabelGenerator: transformations.PodSelectorLabels(agent, componentName), - PortsBuilder: ports.NewPortsBuilder(agent), - } -} diff --git a/pkg/k8s/object/builders/agent/headless-service/headless-service_test.go b/pkg/k8s/object/builders/agent/headless-service/headless-service_test.go index adfd9272..8c905b98 100644 --- a/pkg/k8s/object/builders/agent/headless-service/headless-service_test.go +++ b/pkg/k8s/object/builders/agent/headless-service/headless-service_test.go @@ -1,19 +1,7 @@ /* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +(c) Copyright IBM Corp. 2024,2025 */ + package headless_service import ( @@ -63,19 +51,7 @@ func TestHeadlessServiceBuilder_Build(t *testing.T) { Return(map[string]string{"foo": "bar", "hello": "world"}) portsBuilder := mocks.NewMockPortsBuilder(ctrl) - portsBuilder.EXPECT().GetServicePorts( - ports.AgentAPIsPort, - ports.OpenTelemetryLegacyPort, - ports.OpenTelemetryGRPCPort, - ports.OpenTelemetryHTTPPort, - ). - Return( - []corev1.ServicePort{ - { - Name: "headless-service-port", - }, - }, - ) + portsBuilder.EXPECT().GetServicePorts().Return([]corev1.ServicePort{{Name: "headless-service-port"}}) expected := optional.Of[client.Object]( &corev1.Service{ @@ -114,7 +90,7 @@ func TestNewHeadlessServiceBuilder(t *testing.T) { InstanaAgent: agent, Helpers: helpers.NewHelpers(agent), PodSelectorLabelGenerator: transformations.PodSelectorLabels(agent, constants.ComponentInstanaAgent), - PortsBuilder: ports.NewPortsBuilder(agent), + PortsBuilder: ports.NewPortsBuilder(agent.Spec.OpenTelemetry), } actual := NewHeadlessServiceBuilder(agent) diff --git a/pkg/k8s/object/builders/agent/secrets/config.go b/pkg/k8s/object/builders/agent/secrets/config.go index 86329b06..7ecf4bf6 100644 --- a/pkg/k8s/object/builders/agent/secrets/config.go +++ b/pkg/k8s/object/builders/agent/secrets/config.go @@ -1,5 +1,5 @@ /* -(c) Copyright IBM Corp. 2024 +(c) Copyright IBM Corp. 2024,2025 */ package secrets @@ -87,7 +87,7 @@ func (c *configBuilder) data() (map[string][]byte, error) { if c.Spec.Agent.ConfigurationYaml != "" { data["configuration.yaml"] = []byte(c.Spec.Agent.ConfigurationYaml) } - if otlp := c.Spec.OpenTelemetry; otlp.IsEnabled() { + if otlp := c.Spec.OpenTelemetry; *otlp.Enabled.Enabled { mrshl, _ := yaml.Marshal(map[string]instanav1.OpenTelemetry{"com.instana.plugin.opentelemetry": otlp}) data["configuration-opentelemetry.yaml"] = mrshl } diff --git a/pkg/k8s/object/builders/agent/secrets/config_test.go b/pkg/k8s/object/builders/agent/secrets/config_test.go index 5c0b33a3..b51b2ac9 100644 --- a/pkg/k8s/object/builders/agent/secrets/config_test.go +++ b/pkg/k8s/object/builders/agent/secrets/config_test.go @@ -1,5 +1,5 @@ /* -(c) Copyright IBM Corp. 2024 +(c) Copyright IBM Corp. 2024,2025 */ package secrets @@ -69,7 +69,7 @@ func TestAgentSecretConfigBuild(t *testing.T) { }, } otlp := instanav1.OpenTelemetry{ - GRPC: &instanav1.Enabled{}, + GRPC: instanav1.OpenTelemetryPortConfig{}, } secretType := metav1.TypeMeta{ APIVersion: "v1", diff --git a/pkg/k8s/object/builders/agent/service/service.go b/pkg/k8s/object/builders/agent/service/service.go index 1ce90f43..010214ff 100644 --- a/pkg/k8s/object/builders/agent/service/service.go +++ b/pkg/k8s/object/builders/agent/service/service.go @@ -1,3 +1,7 @@ +/* +(c) Copyright IBM Corp. 2024,2025 +*/ + package service import ( @@ -20,10 +24,9 @@ const ( func NewServiceBuilder(agent *instanav1.InstanaAgent) builder.ObjectBuilder { return &serviceBuilder{ - instanaAgent: agent, - + instanaAgent: agent, podSelectorLabelGenerator: transformations.PodSelectorLabels(agent, componentName), - portsBuilder: ports.NewPortsBuilder(agent), + portsBuilder: ports.NewPortsBuilder(agent.Spec.OpenTelemetry), openTelemetrySettings: agent.Spec.OpenTelemetry, } } @@ -44,6 +47,7 @@ func (s *serviceBuilder) IsNamespaced() bool { } func (s *serviceBuilder) build() *corev1.Service { + localPolicy := corev1.ServiceInternalTrafficPolicyLocal return &corev1.Service{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", @@ -54,14 +58,9 @@ func (s *serviceBuilder) build() *corev1.Service { Namespace: s.instanaAgent.Namespace, }, Spec: corev1.ServiceSpec{ - Selector: s.podSelectorLabelGenerator.GetPodSelectorLabels(), - Ports: s.portsBuilder.GetServicePorts( - ports.AgentAPIsPort, - ports.OpenTelemetryLegacyPort, - ports.OpenTelemetryGRPCPort, - ports.OpenTelemetryHTTPPort, - ), - InternalTrafficPolicy: pointer.To(corev1.ServiceInternalTrafficPolicyLocal), + Selector: s.podSelectorLabelGenerator.GetPodSelectorLabels(), + Ports: s.portsBuilder.GetServicePorts(), + InternalTrafficPolicy: &localPolicy, }, } } @@ -72,7 +71,7 @@ func (s *serviceBuilder) Build() optional.Optional[client.Object] { fallthrough case pointer.DerefOrEmpty(s.instanaAgent.Spec.Prometheus.RemoteWrite.Enabled): fallthrough - case s.openTelemetrySettings.IsEnabled(): + case *s.openTelemetrySettings.Enabled.Enabled: return optional.Of[client.Object](s.build()) default: return optional.Empty[client.Object]() diff --git a/pkg/k8s/object/builders/agent/service/service_test.go b/pkg/k8s/object/builders/agent/service/service_test.go index 43831b6a..fdc7b2c6 100644 --- a/pkg/k8s/object/builders/agent/service/service_test.go +++ b/pkg/k8s/object/builders/agent/service/service_test.go @@ -1,18 +1,5 @@ /* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +(c) Copyright IBM Corp. 2024,2025 */ package service @@ -31,7 +18,6 @@ import ( instanav1 "github.com/instana/instana-agent-operator/api/v1" "github.com/instana/instana-agent-operator/mocks" "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/constants" - "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/ports" "github.com/instana/instana-agent-operator/pkg/optional" "github.com/instana/instana-agent-operator/pkg/pointer" ) @@ -46,10 +32,13 @@ func TestServiceBuilder_ComponentName_IsNamespaced(t *testing.T) { } func TestServiceBuilder_Build(t *testing.T) { + disabled := false + enabled := true + for _, serviceCreate := range []*bool{nil, pointer.To(true), pointer.To(false)} { for _, remoteWriteEnabled := range []instanav1.Enabled{ - {Enabled: pointer.To(true)}, - {Enabled: pointer.To(false)}, + {Enabled: &enabled}, + {Enabled: &disabled}, {Enabled: nil}, } { for _, otlpIsEnabled := range []bool{true, false} { @@ -84,14 +73,14 @@ func TestServiceBuilder_Build(t *testing.T) { if !pointer.DerefOrEmpty(serviceCreate) && (remoteWriteEnabled.Enabled == nil || !*remoteWriteEnabled.Enabled) { otlpSettings = instanav1.OpenTelemetry{ Enabled: instanav1.Enabled{Enabled: &otlpIsEnabled}, - GRPC: &instanav1.Enabled{Enabled: &otlpIsEnabled}, - HTTP: &instanav1.Enabled{Enabled: &otlpIsEnabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &otlpIsEnabled}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &otlpIsEnabled}, } } else { otlpSettings = instanav1.OpenTelemetry{ Enabled: instanav1.Enabled{Enabled: pointer.To(false)}, - GRPC: &instanav1.Enabled{Enabled: pointer.To(false)}, - HTTP: &instanav1.Enabled{Enabled: pointer.To(false)}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: pointer.To(false)}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: pointer.To(false)}, } } @@ -119,12 +108,7 @@ func TestServiceBuilder_Build(t *testing.T) { {Name: rand.String(rand.IntnRange(1, 15))}, {Name: rand.String(rand.IntnRange(1, 15))}, } - portsBuilder.EXPECT().GetServicePorts( - ports.AgentAPIsPort, - ports.OpenTelemetryLegacyPort, - ports.OpenTelemetryGRPCPort, - ports.OpenTelemetryHTTPPort, - ).Return(expectedServicePorts) + portsBuilder.EXPECT().GetServicePorts().Return(expectedServicePorts) expected := optional.Of[client.Object]( &corev1.Service{ diff --git a/pkg/k8s/object/builders/common/env/env_builder.go b/pkg/k8s/object/builders/common/env/env_builder.go index 3b272840..7c205c4c 100644 --- a/pkg/k8s/object/builders/common/env/env_builder.go +++ b/pkg/k8s/object/builders/common/env/env_builder.go @@ -54,6 +54,10 @@ const ( PodNamespaceEnv K8sServiceDomainEnv EnableAgentSocketEnv + InstanaOpenTelemetryGRPCEnabled + InstanaOpenTelemetryGRPCPort + InstanaOpenTelemetryHTTPEnabled + InstanaOpenTelemetryHTTPPort ) type EnvBuilder interface { @@ -160,6 +164,14 @@ func (e *envBuilder) build(envVar EnvVar) *corev1.EnvVar { return &corev1.EnvVar{Name: "K8S_SERVICE_DOMAIN", Value: e.helpers.HeadlessServiceName() + "." + e.agent.Namespace + ".svc"} case EnableAgentSocketEnv: return boolToEnvVar("ENABLE_AGENT_SOCKET", e.agent.Spec.Agent.ServiceMesh.Enabled) + case InstanaOpenTelemetryGRPCEnabled: + return boolToEnvVar("INSTANA_AGENT_OTEL_GRPC", *e.agent.Spec.OpenTelemetry.GRPC.Enabled) + case InstanaOpenTelemetryGRPCPort: + return int32ToEnvVar("INSTANA_AGENT_OTEL_GRPC_PORT", *e.agent.Spec.OpenTelemetry.GRPC.Port) + case InstanaOpenTelemetryHTTPEnabled: + return boolToEnvVar("INSTANA_AGENT_OTEL_HTTP", *e.agent.Spec.OpenTelemetry.HTTP.Enabled) + case InstanaOpenTelemetryHTTPPort: + return int32ToEnvVar("INSTANA_AGENT_OTEL_HTTP_PORT", *e.agent.Spec.OpenTelemetry.HTTP.Port) default: panic(errors.New("unknown environment variable requested")) } @@ -278,3 +290,13 @@ func boolToEnvVar(name string, val bool) *corev1.EnvVar { } return &corev1.EnvVar{Name: name, Value: strconv.FormatBool(val)} } + +// int32ToEnvVar is a utility function to convert int32 to k8s corev1.EnvVar +func int32ToEnvVar(name string, val int32) *corev1.EnvVar { + return intToEnvVar(name, int(val)) +} + +// intToEnvVar is a utility function to convert int to k8s corev1.EnvVar +func intToEnvVar(name string, val int) *corev1.EnvVar { + return &corev1.EnvVar{Name: name, Value: strconv.Itoa(val)} +} diff --git a/pkg/k8s/object/builders/common/ports/helpers.go b/pkg/k8s/object/builders/common/ports/helpers.go deleted file mode 100644 index 8db821e2..00000000 --- a/pkg/k8s/object/builders/common/ports/helpers.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ports - -import ( - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/intstr" -) - -func toServicePort(port InstanaAgentPort) corev1.ServicePort { - return corev1.ServicePort{ - Name: port.String(), - Protocol: corev1.ProtocolTCP, - Port: port.PortNumber(), - TargetPort: intstr.FromString(port.String()), - } -} - -func toContainerPort(port InstanaAgentPort) corev1.ContainerPort { - return corev1.ContainerPort{ - Name: port.String(), - ContainerPort: port.PortNumber(), - Protocol: corev1.ProtocolTCP, - } -} diff --git a/pkg/k8s/object/builders/common/ports/instana_agent_port.go b/pkg/k8s/object/builders/common/ports/instana_agent_port.go deleted file mode 100644 index c5848397..00000000 --- a/pkg/k8s/object/builders/common/ports/instana_agent_port.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ports - -import ( - "errors" - - instanav1 "github.com/instana/instana-agent-operator/api/v1" -) - -type InstanaAgentPort string - -const ( - AgentAPIsPort InstanaAgentPort = "agent-apis" - AgentAPIsPortNumber int32 = 42699 - OpenTelemetryLegacyPort InstanaAgentPort = "otlp-legacy" - OpenTelemetryLegacyPortNumber int32 = 55680 - OpenTelemetryGRPCPort InstanaAgentPort = "otlp-grpc" - OpenTelemetryGRPCPortNumber int32 = 4317 - OpenTelemetryHTTPPort InstanaAgentPort = "otlp-http" - OpenTelemetryHTTPPortNumber int32 = 4318 -) - -func (p InstanaAgentPort) String() string { - return string(p) -} - -func (p InstanaAgentPort) PortNumber() int32 { - switch p { - case AgentAPIsPort: - return AgentAPIsPortNumber - case OpenTelemetryLegacyPort: - return OpenTelemetryLegacyPortNumber - case OpenTelemetryGRPCPort: - return OpenTelemetryGRPCPortNumber - case OpenTelemetryHTTPPort: - return OpenTelemetryHTTPPortNumber - default: - panic(errors.New("unknown port requested")) - } -} - -func (p InstanaAgentPort) IsEnabled(openTelemetrySettings instanav1.OpenTelemetry) bool { - if p == OpenTelemetryLegacyPort || p == OpenTelemetryGRPCPort { - return openTelemetrySettings.GrpcIsEnabled() - } - if p == OpenTelemetryHTTPPort { - return openTelemetrySettings.HttpIsEnabled() - } - // AgentAPIsPort is always enabled - return true -} diff --git a/pkg/k8s/object/builders/common/ports/instana_agent_port_config.go b/pkg/k8s/object/builders/common/ports/instana_agent_port_config.go new file mode 100644 index 00000000..db5025b6 --- /dev/null +++ b/pkg/k8s/object/builders/common/ports/instana_agent_port_config.go @@ -0,0 +1,55 @@ +/* +(c) Copyright IBM Corp. 2024,2025 +*/ + +package ports + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +var InstanaAgentAPIPortConfig = InstanaAgentPortConfig{ + Name: "agent-apis", + Port: 42699, +} + +var OpenTelemetryLegacyPortConfig = InstanaAgentPortConfig{ + Name: "otlp-legacy", + Port: 55680, +} + +var DefaultOpenTelemetryGRPCPortConfig = InstanaAgentPortConfig{ + Name: "otlp-grpc", + Port: 4317, +} + +var DefaultOpenTelemetryHTTPPortConfig = InstanaAgentPortConfig{ + Name: "otlp-http", + Port: 4318, +} + +// InstanaAgentPortConfig is a config that represents the values that are used to create corev1.ServicePorts and corev1.ContainerPorts +type InstanaAgentPortConfig struct { + Name string + Port int32 +} + +// AsServicePort is a simple conversion function from our InstananAgentPortConfig to corev1.ServicePort +func (i *InstanaAgentPortConfig) AsServicePort() corev1.ServicePort { + return corev1.ServicePort{ + Name: i.Name, + Protocol: corev1.ProtocolTCP, + Port: i.Port, + TargetPort: intstr.FromInt32(i.Port), + } +} + +// AsContainerPort is a simple conversion function from our InstanaAgentPortConfig to corev1.ContainerPort +func (i *InstanaAgentPortConfig) AsContainerPort() corev1.ContainerPort { + return corev1.ContainerPort{ + Name: i.Name, + ContainerPort: i.Port, + Protocol: corev1.ProtocolTCP, + } +} diff --git a/pkg/k8s/object/builders/common/ports/ports_builder.go b/pkg/k8s/object/builders/common/ports/ports_builder.go index 420bb32b..7eade1d0 100644 --- a/pkg/k8s/object/builders/common/ports/ports_builder.go +++ b/pkg/k8s/object/builders/common/ports/ports_builder.go @@ -1,58 +1,73 @@ /* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +(c) Copyright IBM Corp. 2024,2025 */ package ports import ( instanav1 "github.com/instana/instana-agent-operator/api/v1" - "github.com/instana/instana-agent-operator/pkg/collections/list" corev1 "k8s.io/api/core/v1" ) type PortsBuilder interface { - GetServicePorts(ports ...InstanaAgentPort) []corev1.ServicePort - GetContainerPorts(ports ...InstanaAgentPort) []corev1.ContainerPort + GetServicePorts() []corev1.ServicePort + GetContainerPorts() []corev1.ContainerPort } type portsBuilder struct { - InstanaAgent *instanav1.InstanaAgent + otel instanav1.OpenTelemetry } -func NewPortsBuilder(agent *instanav1.InstanaAgent) PortsBuilder { - return &portsBuilder{ - InstanaAgent: agent, - } +func NewPortsBuilder(otel instanav1.OpenTelemetry) PortsBuilder { + return &portsBuilder{otel} } -func (p *portsBuilder) GetServicePorts(ports ...InstanaAgentPort) []corev1.ServicePort { - enabledPorts := list.NewListFilter[InstanaAgentPort]().Filter( - ports, func(port InstanaAgentPort) bool { - return port.IsEnabled(p.InstanaAgent.Spec.OpenTelemetry) - }, - ) +// GetServicePorts is responsible of creating a list of service ports based on the InstanaAgent configuration +func (p *portsBuilder) GetServicePorts() []corev1.ServicePort { + servicePorts := []corev1.ServicePort{InstanaAgentAPIPortConfig.AsServicePort()} + if *p.otel.Enabled.Enabled != false { + if *p.otel.GRPC.Enabled { + GRPCPortConfig := DefaultOpenTelemetryGRPCPortConfig + // Override default value if the config contains a new port number + if p.otel.GRPC.Port != nil { + GRPCPortConfig.Port = *p.otel.GRPC.Port + } + servicePorts = append(servicePorts, GRPCPortConfig.AsServicePort(), OpenTelemetryLegacyPortConfig.AsServicePort()) + } + if *p.otel.HTTP.Enabled { + HTTPPortConfig := DefaultOpenTelemetryHTTPPortConfig + // Override default value if the config contains a new port number + if p.otel.HTTP.Port != nil { + HTTPPortConfig.Port = *p.otel.HTTP.Port + } + servicePorts = append(servicePorts, HTTPPortConfig.AsServicePort()) + } + } - return list.NewListMapTo[InstanaAgentPort, corev1.ServicePort]().MapTo(enabledPorts, toServicePort) + return servicePorts } -func (p *portsBuilder) GetContainerPorts(ports ...InstanaAgentPort) []corev1.ContainerPort { - enabledPorts := list.NewListFilter[InstanaAgentPort]().Filter( - ports, func(port InstanaAgentPort) bool { - return port.IsEnabled(p.InstanaAgent.Spec.OpenTelemetry) - }, - ) - return list.NewListMapTo[InstanaAgentPort, corev1.ContainerPort]().MapTo(enabledPorts, toContainerPort) +// GetContainerPorts is responsible of creating a list of container ports based on the InstanaAgent configuration +func (p *portsBuilder) GetContainerPorts() []corev1.ContainerPort { + containerPorts := []corev1.ContainerPort{InstanaAgentAPIPortConfig.AsContainerPort()} + if *p.otel.Enabled.Enabled != false { + if *p.otel.GRPC.Enabled { + GRPCPortConfig := DefaultOpenTelemetryGRPCPortConfig + // Override default value if the config contains a new port number + if p.otel.GRPC.Port != nil { + GRPCPortConfig.Port = *p.otel.GRPC.Port + } + containerPorts = append(containerPorts, GRPCPortConfig.AsContainerPort(), OpenTelemetryLegacyPortConfig.AsContainerPort()) + } + if *p.otel.HTTP.Enabled { + HTTPPortConfig := DefaultOpenTelemetryHTTPPortConfig + // Override default value if the config contains a new port number + if p.otel.HTTP.Port != nil { + HTTPPortConfig.Port = *p.otel.HTTP.Port + } + containerPorts = append(containerPorts, HTTPPortConfig.AsContainerPort()) + } + } + + return containerPorts } diff --git a/pkg/k8s/object/builders/common/ports/ports_builder_test.go b/pkg/k8s/object/builders/common/ports/ports_builder_test.go new file mode 100644 index 00000000..f078aed9 --- /dev/null +++ b/pkg/k8s/object/builders/common/ports/ports_builder_test.go @@ -0,0 +1,211 @@ +/* +(c) Copyright IBM Corp. 2024,2025 +*/ + +package ports_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + + instanav1 "github.com/instana/instana-agent-operator/api/v1" + "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/ports" +) + +func TestPortsBuilderGetPorts(t *testing.T) { + enabled := true + disabled := false + + for _, test := range []struct { + name string + openTelemetrySettings instanav1.OpenTelemetry + expectedContainerPorts []corev1.ContainerPort + expectedServicePorts []corev1.ServicePort + }{ + { + name: "Enabled all with opt-in", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &enabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &enabled}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &enabled}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + ports.DefaultOpenTelemetryGRPCPortConfig.AsContainerPort(), + ports.OpenTelemetryLegacyPortConfig.AsContainerPort(), + ports.DefaultOpenTelemetryHTTPPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + ports.DefaultOpenTelemetryGRPCPortConfig.AsServicePort(), + ports.OpenTelemetryLegacyPortConfig.AsServicePort(), + ports.DefaultOpenTelemetryHTTPPortConfig.AsServicePort(), + }, + }, + { + name: "Enabled only GPRC", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &enabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &enabled}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &disabled}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + ports.DefaultOpenTelemetryGRPCPortConfig.AsContainerPort(), + ports.OpenTelemetryLegacyPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + ports.DefaultOpenTelemetryGRPCPortConfig.AsServicePort(), + ports.OpenTelemetryLegacyPortConfig.AsServicePort(), + }, + }, + { + name: "Enabled only HTTP", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &enabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &disabled}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &enabled}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + ports.DefaultOpenTelemetryHTTPPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + ports.DefaultOpenTelemetryHTTPPortConfig.AsServicePort(), + }, + }, + { + name: "Disable all OLTP ports without legacy setting", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &disabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &disabled}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &disabled}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + }, + }, + { + name: "Disable all OLTP ports via legacy setting", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &disabled}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + }, + }, + { + name: "Conflicting supported and legacy settings", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &disabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &enabled}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &enabled}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + }, + }, + } { + assertions := require.New(t) + portsBuilder := ports.NewPortsBuilder(test.openTelemetrySettings) + assertions.Equal(test.expectedContainerPorts, portsBuilder.GetContainerPorts(), "Occurred in: "+test.name) + assertions.Equal(test.expectedServicePorts, portsBuilder.GetServicePorts(), "Occurred in: "+test.name) + } +} + +func TestPortsBuilderOverridePorts(t *testing.T) { + enabled := true + GRPCPort := int32(1234) + GRPCPortConfig := ports.DefaultOpenTelemetryGRPCPortConfig + GRPCPortConfig.Port = GRPCPort + + HTTPPort := int32(4567) + HTTPPortConfig := ports.DefaultOpenTelemetryHTTPPortConfig + HTTPPortConfig.Port = HTTPPort + + for _, test := range []struct { + name string + openTelemetrySettings instanav1.OpenTelemetry + expectedContainerPorts []corev1.ContainerPort + expectedServicePorts []corev1.ServicePort + }{ + { + name: "Both GRPC and HTTP ports are overwritten with another port number specified in OpenTelemetry", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &enabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &enabled, Port: &GRPCPort}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &enabled, Port: &HTTPPort}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + GRPCPortConfig.AsContainerPort(), + ports.OpenTelemetryLegacyPortConfig.AsContainerPort(), + HTTPPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + GRPCPortConfig.AsServicePort(), + ports.OpenTelemetryLegacyPortConfig.AsServicePort(), + HTTPPortConfig.AsServicePort(), + }, + }, + { + name: "Only HTTP port is overwritten with another port number specified in OpenTelemetry", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &enabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &enabled}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &enabled, Port: &HTTPPort}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + ports.DefaultOpenTelemetryGRPCPortConfig.AsContainerPort(), + ports.OpenTelemetryLegacyPortConfig.AsContainerPort(), + HTTPPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + ports.DefaultOpenTelemetryGRPCPortConfig.AsServicePort(), + ports.OpenTelemetryLegacyPortConfig.AsServicePort(), + HTTPPortConfig.AsServicePort(), + }, + }, + { + name: "Only GRPC port is overwritten with another port number specified in OpenTelemetry", + openTelemetrySettings: instanav1.OpenTelemetry{ + Enabled: instanav1.Enabled{Enabled: &enabled}, + GRPC: instanav1.OpenTelemetryPortConfig{Enabled: &enabled, Port: &GRPCPort}, + HTTP: instanav1.OpenTelemetryPortConfig{Enabled: &enabled}, + }, + expectedContainerPorts: []corev1.ContainerPort{ + ports.InstanaAgentAPIPortConfig.AsContainerPort(), + GRPCPortConfig.AsContainerPort(), + ports.OpenTelemetryLegacyPortConfig.AsContainerPort(), + ports.DefaultOpenTelemetryHTTPPortConfig.AsContainerPort(), + }, + expectedServicePorts: []corev1.ServicePort{ + ports.InstanaAgentAPIPortConfig.AsServicePort(), + GRPCPortConfig.AsServicePort(), + ports.OpenTelemetryLegacyPortConfig.AsServicePort(), + ports.DefaultOpenTelemetryHTTPPortConfig.AsServicePort(), + }, + }, + } { + assertions := require.New(t) + portsBuilder := ports.NewPortsBuilder(test.openTelemetrySettings) + assertions.Equal(test.expectedContainerPorts, portsBuilder.GetContainerPorts(), "Occurred in: "+test.name) + assertions.Equal(test.expectedServicePorts, portsBuilder.GetServicePorts(), "Occurred in: "+test.name) + } +} diff --git a/pkg/k8s/object/builders/common/ports/ports_test.go b/pkg/k8s/object/builders/common/ports/ports_test.go deleted file mode 100644 index fd9e46e4..00000000 --- a/pkg/k8s/object/builders/common/ports/ports_test.go +++ /dev/null @@ -1,259 +0,0 @@ -/* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ports_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/intstr" - - instanav1 "github.com/instana/instana-agent-operator/api/v1" - "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/ports" -) - -func TestInstanaAgentPortMappings(t *testing.T) { - enabled := true - disabled := false - - for _, test := range []struct { - name string - port ports.InstanaAgentPort - openTelemetrySettings instanav1.OpenTelemetry - expectedPortNumber int32 - expectEnabled bool - expectPanic bool - }{ - { - name: string(ports.AgentAPIsPort), - port: ports.AgentAPIsPort, - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, GRPC: &instanav1.Enabled{Enabled: &enabled}}, - expectedPortNumber: ports.AgentAPIsPortNumber, - expectEnabled: true, - }, - - { - name: string(ports.OpenTelemetryLegacyPort) + "_not_enabled", - port: ports.OpenTelemetryLegacyPort, - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, GRPC: &instanav1.Enabled{Enabled: &disabled}}, - expectedPortNumber: ports.OpenTelemetryLegacyPortNumber, - expectEnabled: false, - }, - { - name: string(ports.OpenTelemetryLegacyPort) + "_enabled", - port: ports.OpenTelemetryLegacyPort, - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, GRPC: &instanav1.Enabled{Enabled: &enabled}}, - expectedPortNumber: ports.OpenTelemetryLegacyPortNumber, - expectEnabled: true, - }, - - { - name: string(ports.OpenTelemetryGRPCPort) + "_not_enabled", - port: ports.OpenTelemetryGRPCPort, - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, GRPC: &instanav1.Enabled{Enabled: &disabled}}, - expectedPortNumber: ports.OpenTelemetryGRPCPortNumber, - expectEnabled: false, - }, - { - name: string(ports.OpenTelemetryGRPCPort) + "_enabled", - port: ports.OpenTelemetryGRPCPort, - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, GRPC: &instanav1.Enabled{Enabled: &enabled}}, - expectedPortNumber: ports.OpenTelemetryGRPCPortNumber, - expectEnabled: true, - }, - - { - name: string(ports.OpenTelemetryHTTPPort) + "_not_enabled", - port: ports.OpenTelemetryHTTPPort, - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, HTTP: &instanav1.Enabled{Enabled: &disabled}}, - expectedPortNumber: ports.OpenTelemetryHTTPPortNumber, - expectEnabled: false, - }, - { - name: string(ports.OpenTelemetryHTTPPort) + "_enabled", - port: ports.OpenTelemetryHTTPPort, - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, HTTP: &instanav1.Enabled{Enabled: &enabled}}, - expectedPortNumber: ports.OpenTelemetryHTTPPortNumber, - expectEnabled: true, - }, - { - name: "unknown_port", - port: ports.InstanaAgentPort("unknown"), - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}}, - expectEnabled: true, - expectPanic: true, - }, - } { - t.Run( - test.name, func(t *testing.T) { - assertions := require.New(t) - - assertions.Equal(string(test.port), test.port.String()) - assertions.Equal(test.expectEnabled, test.port.IsEnabled(test.openTelemetrySettings)) - - if test.expectPanic { - assertions.PanicsWithError( - "unknown port requested", func() { - test.port.PortNumber() - }, - ) - } else { - assertions.Equal(test.expectedPortNumber, test.port.PortNumber()) - } - }, - ) - } -} - -func TestPortsBuilderGetPorts(t *testing.T) { - enabled := true - disabled := false - - containerPortAgentAPI := corev1.ContainerPort{ - Name: string(ports.AgentAPIsPort), - ContainerPort: ports.AgentAPIsPortNumber, - Protocol: corev1.ProtocolTCP, - } - - containerPortOtelGPRC := corev1.ContainerPort{ - Name: string(ports.OpenTelemetryGRPCPort), - ContainerPort: ports.OpenTelemetryGRPCPortNumber, - Protocol: corev1.ProtocolTCP, - } - - containerPortOtelHTTP := corev1.ContainerPort{ - Name: string(ports.OpenTelemetryHTTPPort), - ContainerPort: ports.OpenTelemetryHTTPPortNumber, - Protocol: corev1.ProtocolTCP, - } - - containerPortOtelLegacy := corev1.ContainerPort{ - Name: string(ports.OpenTelemetryLegacyPort), - ContainerPort: ports.OpenTelemetryLegacyPortNumber, - Protocol: corev1.ProtocolTCP, - } - - servicePortAgentAPI := corev1.ServicePort{ - Name: string(ports.AgentAPIsPort), - Port: ports.AgentAPIsPortNumber, - TargetPort: intstr.FromString(string(ports.AgentAPIsPort)), - Protocol: corev1.ProtocolTCP, - } - - servicePortOtelGRPC := corev1.ServicePort{ - Name: string(ports.OpenTelemetryGRPCPort), - Port: ports.OpenTelemetryGRPCPortNumber, - TargetPort: intstr.FromString(string(ports.OpenTelemetryGRPCPort)), - Protocol: corev1.ProtocolTCP, - } - - servicePortOtelLegacy := corev1.ServicePort{ - Name: string(ports.OpenTelemetryLegacyPort), - Port: ports.OpenTelemetryLegacyPortNumber, - TargetPort: intstr.FromString(string(ports.OpenTelemetryLegacyPort)), - Protocol: corev1.ProtocolTCP, - } - - servicePortOtelHTTP := corev1.ServicePort{ - Name: string(ports.OpenTelemetryHTTPPort), - Port: ports.OpenTelemetryHTTPPortNumber, - TargetPort: intstr.FromString(string(ports.OpenTelemetryHTTPPort)), - Protocol: corev1.ProtocolTCP, - } - - for _, test := range []struct { - name string - openTelemetrySettings instanav1.OpenTelemetry - expectedContainerPorts []corev1.ContainerPort - expectedServicePorts []corev1.ServicePort - }{ - { - name: "Enabled all by default", - openTelemetrySettings: instanav1.OpenTelemetry{}, - expectedContainerPorts: []corev1.ContainerPort{containerPortAgentAPI, containerPortOtelGPRC, containerPortOtelHTTP, containerPortOtelLegacy}, - expectedServicePorts: []corev1.ServicePort{servicePortAgentAPI, servicePortOtelGRPC, servicePortOtelHTTP, servicePortOtelLegacy}, - }, - { - name: "Enabled all with opt-in", - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, GRPC: &instanav1.Enabled{Enabled: &enabled}, HTTP: &instanav1.Enabled{Enabled: &enabled}}, - expectedContainerPorts: []corev1.ContainerPort{containerPortAgentAPI, containerPortOtelGPRC, containerPortOtelHTTP, containerPortOtelLegacy}, - expectedServicePorts: []corev1.ServicePort{servicePortAgentAPI, servicePortOtelGRPC, servicePortOtelHTTP, servicePortOtelLegacy}, - }, - { - name: "Enabled only GPRC", - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, GRPC: &instanav1.Enabled{Enabled: &enabled}, HTTP: &instanav1.Enabled{Enabled: &disabled}}, - expectedContainerPorts: []corev1.ContainerPort{containerPortAgentAPI, containerPortOtelGPRC, containerPortOtelLegacy}, - expectedServicePorts: []corev1.ServicePort{servicePortAgentAPI, servicePortOtelGRPC, servicePortOtelLegacy}, - }, - { - name: "Enabled only HTTP", - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &enabled}, GRPC: &instanav1.Enabled{Enabled: &disabled}, HTTP: &instanav1.Enabled{Enabled: &enabled}}, - expectedContainerPorts: []corev1.ContainerPort{containerPortAgentAPI, containerPortOtelHTTP}, - expectedServicePorts: []corev1.ServicePort{servicePortAgentAPI, servicePortOtelHTTP}, - }, - { - name: "Disable all OLTP ports without legacy setting", - openTelemetrySettings: instanav1.OpenTelemetry{GRPC: &instanav1.Enabled{Enabled: &disabled}, HTTP: &instanav1.Enabled{Enabled: &disabled}}, - expectedContainerPorts: []corev1.ContainerPort{containerPortAgentAPI}, - expectedServicePorts: []corev1.ServicePort{servicePortAgentAPI}, - }, - { - name: "Disable all OLTP ports via legacy setting", - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &disabled}}, - expectedContainerPorts: []corev1.ContainerPort{containerPortAgentAPI}, - expectedServicePorts: []corev1.ServicePort{servicePortAgentAPI}, - }, - { - name: "Conflicting supported and legacy settings", - openTelemetrySettings: instanav1.OpenTelemetry{Enabled: instanav1.Enabled{Enabled: &disabled}, GRPC: &instanav1.Enabled{Enabled: &enabled}, HTTP: &instanav1.Enabled{Enabled: &enabled}}, - expectedContainerPorts: []corev1.ContainerPort{containerPortAgentAPI, containerPortOtelGPRC, containerPortOtelHTTP, containerPortOtelLegacy}, - expectedServicePorts: []corev1.ServicePort{servicePortAgentAPI, servicePortOtelGRPC, servicePortOtelHTTP, servicePortOtelLegacy}, - }, - } { - assertions := require.New(t) - actualContainerPorts := ports. - NewPortsBuilder(&instanav1.InstanaAgent{ - Spec: instanav1.InstanaAgentSpec{ - OpenTelemetry: test.openTelemetrySettings, - }, - }). - GetContainerPorts( - ports.AgentAPIsPort, - ports.OpenTelemetryGRPCPort, - ports.OpenTelemetryHTTPPort, - ports.OpenTelemetryLegacyPort, - ) - - actualServicePorts := ports. - NewPortsBuilder(&instanav1.InstanaAgent{ - Spec: instanav1.InstanaAgentSpec{ - OpenTelemetry: test.openTelemetrySettings, - }, - }). - GetServicePorts( - ports.AgentAPIsPort, - ports.OpenTelemetryGRPCPort, - ports.OpenTelemetryHTTPPort, - ports.OpenTelemetryLegacyPort, - ) - - assertions.Equal(test.expectedContainerPorts, actualContainerPorts, test.openTelemetrySettings) - assertions.Equal(test.expectedServicePorts, actualServicePorts, test.openTelemetrySettings) - } -} diff --git a/pkg/k8s/object/builders/k8s-sensor/deployment/deployment.go b/pkg/k8s/object/builders/k8s-sensor/deployment/deployment.go index 55604482..a08a50bf 100644 --- a/pkg/k8s/object/builders/k8s-sensor/deployment/deployment.go +++ b/pkg/k8s/object/builders/k8s-sensor/deployment/deployment.go @@ -1,6 +1,5 @@ /* -(c) Copyright IBM Corp. 2024 -(c) Copyright Instana Inc. 2024 +(c) Copyright IBM Corp. 2024,2025 */ package deployment @@ -142,7 +141,7 @@ func (d *deploymentBuilder) build() *appsv1.Deployment { Env: d.getEnvVars(), VolumeMounts: mounts, Resources: d.Spec.K8sSensor.DeploymentSpec.Pod.ResourceRequirements.GetOrDefault(), - Ports: d.PortsBuilder.GetContainerPorts(ports.AgentAPIsPort), + Ports: []corev1.ContainerPort{ports.InstanaAgentAPIPortConfig.AsContainerPort()}, }, }, Volumes: volumes, @@ -208,7 +207,7 @@ func NewDeploymentBuilder( PodSelectorLabelGenerator: transformations.PodSelectorLabels(agent, componentName), EnvBuilder: env.NewEnvBuilder(agent, nil), VolumeBuilder: volume.NewVolumeBuilder(agent, isOpenShift), - PortsBuilder: ports.NewPortsBuilder(agent), + PortsBuilder: ports.NewPortsBuilder(agent.Spec.OpenTelemetry), backend: backend, } }