From 4d69f9c821f81660aa51ea3e39d95e441e0f947e Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Fri, 17 Oct 2025 12:40:15 +0200 Subject: [PATCH 01/27] fix --- .../v1alpha1/logpipeline_conversion.go | 16 +- .../v1alpha1/metricpipeline_conversion.go | 398 ++++++ .../metricpipeline_conversion_test.go | 1255 +++++++++++++++++ .../v1alpha1/shared_types_conversion.go | 30 + .../v1beta1/metricpipeline_conversion.go | 5 + internal/webhookcert/resources.go | 21 +- main.go | 14 +- 7 files changed, 1720 insertions(+), 19 deletions(-) create mode 100644 apis/telemetry/v1alpha1/metricpipeline_conversion.go create mode 100644 apis/telemetry/v1alpha1/metricpipeline_conversion_test.go create mode 100644 apis/telemetry/v1alpha1/shared_types_conversion.go create mode 100644 apis/telemetry/v1beta1/metricpipeline_conversion.go diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index cbc22c8139..b44b14a139 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -11,7 +11,7 @@ import ( var errSrcTypeUnsupported = errors.New("source type is not LogPipeline v1alpha1") var errDstTypeUnsupported = errors.New("destination type is not LogPipeline v1beta1") -// ConvertTo converts this LogPipeline to the Hub version (v1beta1). +// ConvertTo converts this LogPipeline to the Hub version (v1alpha1 -> v1beta1). func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { src := lp @@ -96,12 +96,8 @@ func v1Alpha1OTLPInputToV1Beta1(otlp *OTLPInput) *telemetryv1beta1.OTLPInput { input := &telemetryv1beta1.OTLPInput{ Disabled: otlp.Disabled, } - if otlp.Namespaces != nil { - input.Namespaces = &telemetryv1beta1.NamespaceSelector{ - Include: otlp.Namespaces.Include, - Exclude: otlp.Namespaces.Exclude, - } - } + + input.Namespaces = convertNamespaceSelectorToBeta(otlp.Namespaces) return input } @@ -114,8 +110,8 @@ func v1Alpha1ApplicationToV1Beta1(application *LogPipelineApplicationInput) *tel runtime := &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: application.Enabled, Namespaces: telemetryv1beta1.LogPipelineNamespaceSelector{ - Include: application.Namespaces.Include, - Exclude: application.Namespaces.Exclude, + Include: sanitizeNamespaceNames(application.Namespaces.Include), + Exclude: sanitizeNamespaceNames(application.Namespaces.Exclude), System: application.Namespaces.System, }, Containers: telemetryv1beta1.LogPipelineContainerSelector{ @@ -252,7 +248,7 @@ func v1Alpha1FilterSpecToV1Beta1(src FilterSpec) telemetryv1beta1.FilterSpec { return dst } -// ConvertFrom converts from the Hub version (v1beta1) to this version. +// ConvertFrom converts from the Hub version (v1beta1 -> v1alpha1) to this version. func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { dst := lp diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion.go b/apis/telemetry/v1alpha1/metricpipeline_conversion.go new file mode 100644 index 0000000000..dfbc6c27c6 --- /dev/null +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion.go @@ -0,0 +1,398 @@ +package v1alpha1 + +import ( + "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/conversion" +) + +// ConvertTo implements conversion.Hub for MetricPipeline (v1alpha1 -> v1beta1) +func (src *MetricPipeline) ConvertTo(dstRaw conversion.Hub) error { + dst, ok := dstRaw.(*telemetryv1beta1.MetricPipeline) + if !ok { + return errDstTypeUnsupported + } + + // Copy metadata + dst.ObjectMeta = src.ObjectMeta + + // Copy Spec fields + dst.Spec.Input = telemetryv1beta1.MetricPipelineInput{} + if src.Spec.Input.Prometheus != nil { + dst.Spec.Input.Prometheus = &telemetryv1beta1.MetricPipelinePrometheusInput{ + Enabled: src.Spec.Input.Prometheus.Enabled, + Namespaces: convertNamespaceSelectorToBeta(src.Spec.Input.Prometheus.Namespaces), + DiagnosticMetrics: convertDiagnosticMetricsToBeta(src.Spec.Input.Prometheus.DiagnosticMetrics), + } + } + if src.Spec.Input.Runtime != nil { + dst.Spec.Input.Runtime = &telemetryv1beta1.MetricPipelineRuntimeInput{ + Enabled: src.Spec.Input.Runtime.Enabled, + Namespaces: convertNamespaceSelectorToBeta(src.Spec.Input.Runtime.Namespaces), + Resources: convertRuntimeResourcesToBeta(src.Spec.Input.Runtime.Resources), + } + } + if src.Spec.Input.Istio != nil { + dst.Spec.Input.Istio = &telemetryv1beta1.MetricPipelineIstioInput{ + Enabled: src.Spec.Input.Istio.Enabled, + Namespaces: convertNamespaceSelectorToBeta(src.Spec.Input.Istio.Namespaces), + DiagnosticMetrics: convertDiagnosticMetricsToBeta(src.Spec.Input.Istio.DiagnosticMetrics), + EnvoyMetrics: convertEnvoyMetricsToBeta(src.Spec.Input.Istio.EnvoyMetrics), + } + } + if src.Spec.Input.OTLP != nil { + dst.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{ + Disabled: src.Spec.Input.OTLP.Disabled, + Namespaces: convertNamespaceSelectorToBeta(src.Spec.Input.OTLP.Namespaces), + } + } + dst.Spec.Output = telemetryv1beta1.MetricPipelineOutput{} + if src.Spec.Output.OTLP != nil { + dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) + } + for _, t := range src.Spec.Transforms { + dst.Spec.Transforms = append(dst.Spec.Transforms, telemetryv1beta1.TransformSpec(t)) + } + for _, f := range src.Spec.Filters { + dst.Spec.Filter = append(dst.Spec.Filter, telemetryv1beta1.FilterSpec(f)) + } + dst.Status = telemetryv1beta1.MetricPipelineStatus(src.Status) + return nil +} + +// ConvertFrom implements conversion.Hub for MetricPipeline (v1beta1 -> v1alpha1) +func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { + src, ok := srcRaw.(*v1beta1.MetricPipeline) + if !ok { + return nil + } + + // Copy metadata + dst.ObjectMeta = src.ObjectMeta + + // Copy Spec fields + dst.Spec.Input = MetricPipelineInput{} + if src.Spec.Input.Prometheus != nil { + dst.Spec.Input.Prometheus = &MetricPipelinePrometheusInput{ + Enabled: src.Spec.Input.Prometheus.Enabled, + Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.Prometheus.Namespaces), + DiagnosticMetrics: convertDiagnosticMetricsToAlpha(src.Spec.Input.Prometheus.DiagnosticMetrics), + } + } + if src.Spec.Input.Runtime != nil { + dst.Spec.Input.Runtime = &MetricPipelineRuntimeInput{ + Enabled: src.Spec.Input.Runtime.Enabled, + Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.Runtime.Namespaces), + Resources: convertRuntimeResourcesToAlpha(src.Spec.Input.Runtime.Resources), + } + } + if src.Spec.Input.Istio != nil { + dst.Spec.Input.Istio = &MetricPipelineIstioInput{ + Enabled: src.Spec.Input.Istio.Enabled, + Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.Istio.Namespaces), + DiagnosticMetrics: convertDiagnosticMetricsToAlpha(src.Spec.Input.Istio.DiagnosticMetrics), + EnvoyMetrics: convertEnvoyMetricsToAlpha(src.Spec.Input.Istio.EnvoyMetrics), + } + } + if src.Spec.Input.OTLP != nil { + dst.Spec.Input.OTLP = &OTLPInput{ + Disabled: src.Spec.Input.OTLP.Disabled, + Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.OTLP.Namespaces), + } + } + dst.Spec.Output = MetricPipelineOutput{} + if src.Spec.Output.OTLP != nil { + dst.Spec.Output.OTLP = convertOTLPOutputToAlpha(src.Spec.Output.OTLP) + } + for _, t := range src.Spec.Transforms { + dst.Spec.Transforms = append(dst.Spec.Transforms, TransformSpec(t)) + } + for _, f := range src.Spec.Filter { + dst.Spec.Filters = append(dst.Spec.Filters, FilterSpec(f)) + } + dst.Status = MetricPipelineStatus(src.Status) + return nil +} + +// Helper conversion functions +func convertNamespaceSelectorToAlpha(ns *telemetryv1beta1.NamespaceSelector) *NamespaceSelector { + if ns == nil { + return nil + } + return &NamespaceSelector{ + Include: append([]string{}, ns.Include...), + Exclude: append([]string{}, ns.Exclude...), + } +} + +func convertDiagnosticMetricsToBeta(dm *MetricPipelineIstioInputDiagnosticMetrics) *telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics { + if dm == nil { + return nil + } + return &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: dm.Enabled, + } +} + +func convertDiagnosticMetricsToAlpha(dm *telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics) *MetricPipelineIstioInputDiagnosticMetrics { + if dm == nil { + return nil + } + return &MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: dm.Enabled, + } +} + +func convertEnvoyMetricsToBeta(em *EnvoyMetrics) *telemetryv1beta1.EnvoyMetrics { + if em == nil { + return nil + } + return &telemetryv1beta1.EnvoyMetrics{ + Enabled: em.Enabled, + } +} + +func convertEnvoyMetricsToAlpha(em *telemetryv1beta1.EnvoyMetrics) *EnvoyMetrics { + if em == nil { + return nil + } + return &EnvoyMetrics{ + Enabled: em.Enabled, + } +} + +func convertRuntimeResourcesToBeta(r *MetricPipelineRuntimeInputResources) *telemetryv1beta1.MetricPipelineRuntimeInputResources { + if r == nil { + return nil + } + return &telemetryv1beta1.MetricPipelineRuntimeInputResources{ + Pod: convertRuntimeResourceToBeta(r.Pod), + Container: convertRuntimeResourceToBeta(r.Container), + Node: convertRuntimeResourceToBeta(r.Node), + Volume: convertRuntimeResourceToBeta(r.Volume), + DaemonSet: convertRuntimeResourceToBeta(r.DaemonSet), + Deployment: convertRuntimeResourceToBeta(r.Deployment), + StatefulSet: convertRuntimeResourceToBeta(r.StatefulSet), + Job: convertRuntimeResourceToBeta(r.Job), + } +} + +func convertRuntimeResourcesToAlpha(r *telemetryv1beta1.MetricPipelineRuntimeInputResources) *MetricPipelineRuntimeInputResources { + if r == nil { + return nil + } + return &MetricPipelineRuntimeInputResources{ + Pod: convertRuntimeResourceToAlpha(r.Pod), + Container: convertRuntimeResourceToAlpha(r.Container), + Node: convertRuntimeResourceToAlpha(r.Node), + Volume: convertRuntimeResourceToAlpha(r.Volume), + DaemonSet: convertRuntimeResourceToAlpha(r.DaemonSet), + Deployment: convertRuntimeResourceToAlpha(r.Deployment), + StatefulSet: convertRuntimeResourceToAlpha(r.StatefulSet), + Job: convertRuntimeResourceToAlpha(r.Job), + } +} + +func convertRuntimeResourceToBeta(r *MetricPipelineRuntimeInputResource) *telemetryv1beta1.MetricPipelineRuntimeInputResource { + if r == nil { + return nil + } + return &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: r.Enabled, + } +} + +func convertRuntimeResourceToAlpha(r *telemetryv1beta1.MetricPipelineRuntimeInputResource) *MetricPipelineRuntimeInputResource { + if r == nil { + return nil + } + return &MetricPipelineRuntimeInputResource{ + Enabled: r.Enabled, + } +} + +func convertOTLPOutputToBeta(o *OTLPOutput) *telemetryv1beta1.OTLPOutput { + if o == nil { + return nil + } + return &telemetryv1beta1.OTLPOutput{ + Protocol: telemetryv1beta1.OTLPProtocol(o.Protocol), + Endpoint: convertValueTypeToBeta(o.Endpoint), + Path: o.Path, + Authentication: convertAuthenticationToBeta(o.Authentication), + Headers: convertHeadersToBeta(o.Headers), + TLS: convertOTLPTLSToBeta(o.TLS), + } +} + +func convertOTLPOutputToAlpha(o *telemetryv1beta1.OTLPOutput) *OTLPOutput { + if o == nil { + return nil + } + return &OTLPOutput{ + Protocol: string(o.Protocol), + Endpoint: convertValueTypeToAlpha(o.Endpoint), + Path: o.Path, + Authentication: convertAuthenticationToAlpha(o.Authentication), + Headers: convertHeadersToAlpha(o.Headers), + TLS: convertOTLPTLSToAlpha(o.TLS), + } +} + +func convertValueTypeToBeta(v ValueType) telemetryv1beta1.ValueType { + return telemetryv1beta1.ValueType{ + Value: v.Value, + ValueFrom: convertValueFromSourceToBeta(v.ValueFrom), + } +} + +func convertValueTypeToAlpha(v telemetryv1beta1.ValueType) ValueType { + return ValueType{ + Value: v.Value, + ValueFrom: convertValueFromSourceToAlpha(v.ValueFrom), + } +} + +func convertValueFromSourceToBeta(v *ValueFromSource) *telemetryv1beta1.ValueFromSource { + if v == nil { + return nil + } + return &telemetryv1beta1.ValueFromSource{ + SecretKeyRef: convertSecretKeyRefToBeta(v.SecretKeyRef), + } +} + +func convertValueFromSourceToAlpha(v *telemetryv1beta1.ValueFromSource) *ValueFromSource { + if v == nil { + return nil + } + return &ValueFromSource{ + SecretKeyRef: convertSecretKeyRefToAlpha(v.SecretKeyRef), + } +} + +func convertSecretKeyRefToBeta(s *SecretKeyRef) *telemetryv1beta1.SecretKeyRef { + if s == nil { + return nil + } + return &telemetryv1beta1.SecretKeyRef{ + Name: s.Name, + Namespace: s.Namespace, + Key: s.Key, + } +} + +func convertSecretKeyRefToAlpha(s *telemetryv1beta1.SecretKeyRef) *SecretKeyRef { + if s == nil { + return nil + } + return &SecretKeyRef{ + Name: s.Name, + Namespace: s.Namespace, + Key: s.Key, + } +} + +func convertAuthenticationToBeta(a *AuthenticationOptions) *telemetryv1beta1.AuthenticationOptions { + if a == nil { + return nil + } + return &telemetryv1beta1.AuthenticationOptions{ + Basic: convertBasicAuthToBeta(a.Basic), + } +} + +func convertAuthenticationToAlpha(a *telemetryv1beta1.AuthenticationOptions) *AuthenticationOptions { + if a == nil { + return nil + } + return &AuthenticationOptions{ + Basic: convertBasicAuthToAlpha(a.Basic), + } +} + +func convertBasicAuthToBeta(b *BasicAuthOptions) *telemetryv1beta1.BasicAuthOptions { + if b == nil { + return nil + } + return &telemetryv1beta1.BasicAuthOptions{ + User: convertValueTypeToBeta(b.User), + Password: convertValueTypeToBeta(b.Password), + } +} + +func convertBasicAuthToAlpha(b *telemetryv1beta1.BasicAuthOptions) *BasicAuthOptions { + if b == nil { + return nil + } + return &BasicAuthOptions{ + User: convertValueTypeToAlpha(b.User), + Password: convertValueTypeToAlpha(b.Password), + } +} + +func convertHeadersToBeta(hs []Header) []telemetryv1beta1.Header { + var out []telemetryv1beta1.Header + for _, h := range hs { + out = append(out, telemetryv1beta1.Header{ + ValueType: convertValueTypeToBeta(h.ValueType), + Name: h.Name, + Prefix: h.Prefix, + }) + } + return out +} + +func convertHeadersToAlpha(hs []telemetryv1beta1.Header) []Header { + var out []Header + for _, h := range hs { + out = append(out, Header{ + ValueType: convertValueTypeToAlpha(h.ValueType), + Name: h.Name, + Prefix: h.Prefix, + }) + } + return out +} + +func convertOTLPTLSToBeta(t *OTLPTLS) *telemetryv1beta1.OutputTLS { + if t == nil { + return nil + } + return &telemetryv1beta1.OutputTLS{ + Disabled: t.Insecure, + SkipCertificateValidation: t.InsecureSkipVerify, + CA: convertValueTypeToBetaPtr(t.CA), + Cert: convertValueTypeToBetaPtr(t.Cert), + Key: convertValueTypeToBetaPtr(t.Key), + } +} + +func convertOTLPTLSToAlpha(t *telemetryv1beta1.OutputTLS) *OTLPTLS { + if t == nil { + return nil + } + return &OTLPTLS{ + Insecure: t.Disabled, + InsecureSkipVerify: t.SkipCertificateValidation, + CA: convertValueTypeToAlphaPtr(t.CA), + Cert: convertValueTypeToAlphaPtr(t.Cert), + Key: convertValueTypeToAlphaPtr(t.Key), + } +} + +func convertValueTypeToBetaPtr(v *ValueType) *telemetryv1beta1.ValueType { + if v == nil { + return nil + } + vt := convertValueTypeToBeta(*v) + return &vt +} + +func convertValueTypeToAlphaPtr(v *telemetryv1beta1.ValueType) *ValueType { + if v == nil { + return nil + } + vt := convertValueTypeToAlpha(*v) + return &vt +} diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go b/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go new file mode 100644 index 0000000000..90b87a94a2 --- /dev/null +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go @@ -0,0 +1,1255 @@ +package v1alpha1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func boolPtr(b bool) *bool { + return &b +} + +func TestMetricPipelineConvertTo(t *testing.T) { + tests := []struct { + name string + input *MetricPipeline + expected *telemetryv1beta1.MetricPipeline + }{ + { + name: "should convert basic fields", + input: &MetricPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pipeline", + Namespace: "test-ns", + }, + Spec: MetricPipelineSpec{}, + }, + expected: &telemetryv1beta1.MetricPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pipeline", + Namespace: "test-ns", + }, + Spec: telemetryv1beta1.MetricPipelineSpec{}, + }, + }, + { + name: "should sanitize namespace selectors", + input: &MetricPipeline{ + Spec: MetricPipelineSpec{ + Input: MetricPipelineInput{ + Runtime: &MetricPipelineRuntimeInput{ + Namespaces: &NamespaceSelector{ + Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, + Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, + }, + }, + }, + }, + }, + expected: &telemetryv1beta1.MetricPipeline{ + Spec: telemetryv1beta1.MetricPipelineSpec{ + Input: telemetryv1beta1.MetricPipelineInput{ + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"valid-ns", "another-valid-ns"}, + Exclude: []string{"valid-excluded", "another-valid-excluded"}, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dst := &telemetryv1beta1.MetricPipeline{} + err := tt.input.ConvertTo(dst) + require.NoError(t, err) + assert.Equal(t, tt.expected, dst) + }) + } +} + +func TestMetricPipelineConvertFrom(t *testing.T) { + tests := []struct { + name string + input *telemetryv1beta1.MetricPipeline + expected *MetricPipeline + }{ + { + name: "should convert basic fields", + input: &telemetryv1beta1.MetricPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pipeline", + Namespace: "test-ns", + }, + Spec: telemetryv1beta1.MetricPipelineSpec{}, + }, + expected: &MetricPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pipeline", + Namespace: "test-ns", + }, + Spec: MetricPipelineSpec{}, + }, + }, + { + name: "should convert namespace selectors without validation", + input: &telemetryv1beta1.MetricPipeline{ + Spec: telemetryv1beta1.MetricPipelineSpec{ + Input: telemetryv1beta1.MetricPipelineInput{ + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"valid-ns", "Invalid_NS"}, + Exclude: []string{"valid-excluded", "Invalid@NS"}, + }, + }, + }, + }, + }, + expected: &MetricPipeline{ + Spec: MetricPipelineSpec{ + Input: MetricPipelineInput{ + Runtime: &MetricPipelineRuntimeInput{ + Namespaces: &NamespaceSelector{ + Include: []string{"valid-ns", "Invalid_NS"}, + Exclude: []string{"valid-excluded", "Invalid@NS"}, + }, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dst := &MetricPipeline{} + err := dst.ConvertFrom(tt.input) + require.NoError(t, err) + assert.Equal(t, tt.expected, dst) + }) + } +} + +func TestMetricPipelineConvertTo_InvalidDestination(t *testing.T) { + src := &MetricPipeline{} + dst := &MetricPipeline{} // Wrong type for destination + err := src.ConvertTo(dst) + assert.Error(t, err) + assert.Contains(t, err.Error(), "dst object must be of type *v1beta1.MetricPipeline") +} + +func TestMetricPipelineConvertFrom_InvalidSource(t *testing.T) { + src := &MetricPipeline{} // Wrong type for source + dst := &MetricPipeline{} + err := dst.ConvertFrom(src) + assert.Error(t, err) + assert.Contains(t, err.Error(), "src object must be of type *v1beta1.MetricPipeline") +} + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func boolPtr(b bool) *bool { + + return &b + +} telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + + + +func TestMetricPipelineConvertTo(t *testing.T) { metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + tests := []struct { + + name string)) + + input *MetricPipeline + + expected *telemetryv1beta1.MetricPipeline + + }{ + + {func boolPtr(b bool) *bool {func boolPtr(b bool) *bool { + + name: "should convert basic fields", + + input: &MetricPipeline{ return &b return &b + + ObjectMeta: metav1.ObjectMeta{ + + Name: "test-pipeline",}} + + Namespace: "test-ns", + + }, + + Spec: MetricPipelineSpec{}, + + },func TestMetricPipelineConvertTo(t *testing.T) {func TestMetricPipelineConvertTo(t *testing.T) { + + expected: &telemetryv1beta1.MetricPipeline{ + + ObjectMeta: metav1.ObjectMeta{ tests := []struct { tests := []struct { + + Name: "test-pipeline", + + Namespace: "test-ns", name string name string + + }, + + Spec: telemetryv1beta1.MetricPipelineSpec{}, input *MetricPipeline input *MetricPipeline + + }, + + }, expected *telemetryv1beta1.MetricPipeline expected *telemetryv1beta1.MetricPipeline + + { + + name: "should sanitize namespaces in namespace selectors", }{ }{ + + input: &MetricPipeline{ + + ObjectMeta: metav1.ObjectMeta{ { { + + Name: "test-pipeline", + + }, name: "should convert basic fields", name: "should convert basic fields", + + Spec: MetricPipelineSpec{ + + Input: MetricPipelineInput{ input: &MetricPipeline{ input: &MetricPipeline{ + + Runtime: &MetricPipelineRuntimeInput{ + + Namespaces: &NamespaceSelector{ ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ + + Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, + + Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, Name: "test-pipeline", Name: "test-pipeline", + + }, + + }, Namespace: "test-ns", Namespace: "test-ns", + + }, + + }, }, }, + + }, + + expected: &telemetryv1beta1.MetricPipeline{ Spec: MetricPipelineSpec{}, Spec: MetricPipelineSpec{}, + + ObjectMeta: metav1.ObjectMeta{ + + Name: "test-pipeline", }, }, + + }, + + Spec: telemetryv1beta1.MetricPipelineSpec{ expected: &telemetryv1beta1.MetricPipeline{ expected: &telemetryv1beta1.MetricPipeline{ + + Input: telemetryv1beta1.MetricPipelineInput{ + + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ + + Namespaces: &telemetryv1beta1.NamespaceSelector{ + + Include: []string{"valid-ns", "another-valid-ns"}, Name: "test-pipeline", Name: "test-pipeline", + + Exclude: []string{"valid-excluded", "another-valid-excluded"}, + + }, Namespace: "test-ns", Namespace: "test-ns", + + }, + + }, }, }, + + }, + + }, Spec: telemetryv1beta1.MetricPipelineSpec{}, Spec: telemetryv1beta1.MetricPipelineSpec{}, + + }, + + { }, }, + + name: "should convert all input sections", + + input: &MetricPipeline{ }, }, + + Spec: MetricPipelineSpec{ + + Input: MetricPipelineInput{ { { + + Prometheus: &MetricPipelinePrometheusInput{ + + Enabled: boolPtr(true), name: "should sanitize namespaces in namespace selectors", name: "should sanitize namespaces in namespace selectors", + + Namespaces: &NamespaceSelector{ + + Include: []string{"ns1"}, input: &MetricPipeline{ input: &MetricPipeline{ + + }, + + }, ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ + + Runtime: &MetricPipelineRuntimeInput{ + + Enabled: boolPtr(true), Name: "test-pipeline", Name: "test-pipeline", + + Resources: &MetricPipelineRuntimeInputResources{ + + Pod: &MetricPipelineRuntimeInputResource{ }, }, + + Enabled: boolPtr(true), + + }, Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ + + }, + + }, Input: MetricPipelineInput{ Input: MetricPipelineInput{ + + Istio: &MetricPipelineIstioInput{ + + Enabled: boolPtr(true), Runtime: &MetricPipelineRuntimeInput{ Runtime: &MetricPipelineRuntimeInput{ + + DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ + + Enabled: boolPtr(true), Namespaces: &NamespaceSelector{ Namespaces: &NamespaceSelector{ + + }, + + }, Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, + + OTLP: &OTLPInput{ + + Disabled: boolPtr(true), Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, + + }, + + }, }, }, + + }, + + }, }, }, + + expected: &telemetryv1beta1.MetricPipeline{ + + Spec: telemetryv1beta1.MetricPipelineSpec{ }, }, + + Input: telemetryv1beta1.MetricPipelineInput{ + + Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ }, }, + + Enabled: boolPtr(true), + + Namespaces: &telemetryv1beta1.NamespaceSelector{ }, }, + + Include: []string{"ns1"}, + + }, expected: &telemetryv1beta1.MetricPipeline{ expected: &telemetryv1beta1.MetricPipeline{ + + }, + + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ + + Enabled: boolPtr(true), + + Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Name: "test-pipeline", Name: "test-pipeline", + + Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + + Enabled: boolPtr(true), }, }, + + }, + + }, Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ + + }, + + Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Input: telemetryv1beta1.MetricPipelineInput{ Input: telemetryv1beta1.MetricPipelineInput{ + + Enabled: boolPtr(true), + + DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ + + Enabled: boolPtr(true), + + }, Namespaces: &telemetryv1beta1.NamespaceSelector{ Namespaces: &telemetryv1beta1.NamespaceSelector{ + + }, + + OTLP: &telemetryv1beta1.OTLPInput{ Include: []string{"valid-ns", "another-valid-ns"}, Include: []string{"valid-ns", "another-valid-ns"}, + + Disabled: boolPtr(true), + + }, Exclude: []string{"valid-excluded", "another-valid-excluded"}, Exclude: []string{"valid-excluded", "another-valid-excluded"}, + + }, + + }, }, }, + + }, + + }, }, }, + + { + + name: "should convert output section with authentication", }, }, + + input: &MetricPipeline{ + + Spec: MetricPipelineSpec{ }, }, + + Output: MetricPipelineOutput{ + + OTLP: &OTLPOutput{ }, }, + + Protocol: "grpc", + + Endpoint: ValueType{ }, }, + + Value: "localhost:4317", + + }, { { + + Authentication: &AuthenticationOptions{ + + Basic: &BasicAuthOptions{ name: "should convert all input sections", name: "should convert all input sections", + + User: ValueType{ + + Value: "user", input: &MetricPipeline{ input: &MetricPipeline{ + + }, + + Password: ValueType{ Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ + + Value: "pass", + + }, Input: MetricPipelineInput{ Input: MetricPipelineInput{ + + }, + + }, Prometheus: &MetricPipelinePrometheusInput{ Prometheus: &MetricPipelinePrometheusInput{ + + }, + + }, Enabled: boolPtr(true), Enabled: true, + + }, + + }, Namespaces: &NamespaceSelector{ Namespaces: &NamespaceSelector{ + + expected: &telemetryv1beta1.MetricPipeline{ + + Spec: telemetryv1beta1.MetricPipelineSpec{ Include: []string{"ns1"}, Include: []string{"ns1"}, + + Output: telemetryv1beta1.MetricPipelineOutput{ + + OTLP: &telemetryv1beta1.OTLPOutput{ }, }, + + Protocol: "grpc", + + Endpoint: telemetryv1beta1.ValueType{ }, }, + + Value: "localhost:4317", + + }, Runtime: &MetricPipelineRuntimeInput{ Runtime: &MetricPipelineRuntimeInput{ + + Authentication: &telemetryv1beta1.AuthenticationOptions{ + + Basic: &telemetryv1beta1.BasicAuthOptions{ Enabled: boolPtr(true), Enabled: true, + + User: telemetryv1beta1.ValueType{ + + Value: "user", Resources: &MetricPipelineRuntimeInputResources{ Resources: &MetricPipelineRuntimeInputResources{ + + }, + + Password: telemetryv1beta1.ValueType{ Pod: &MetricPipelineRuntimeInputResource{ Pod: &MetricPipelineRuntimeInputResource{ + + Value: "pass", + + }, Enabled: boolPtr(true), Enabled: true, + + }, + + }, }, }, + + }, + + }, }, }, + + }, + + }, }, }, + + }, + + } Istio: &MetricPipelineIstioInput{ Istio: &MetricPipelineIstioInput{ + + + + for _, tt := range tests { Enabled: boolPtr(true), Enabled: true, + + t.Run(tt.name, func(t *testing.T) { + + dst := &telemetryv1beta1.MetricPipeline{} DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ + + err := tt.input.ConvertTo(dst) + + assert.NoError(t, err) Enabled: boolPtr(true), Enabled: true, + + assert.Equal(t, tt.expected, dst) + + }) }, }, + + } + +} }, }, + + + +func TestMetricPipelineConvertFrom(t *testing.T) { OTLP: &OTLPInput{ OTLP: &OTLPInput{ + + tests := []struct { + + name string Disabled: boolPtr(true), Disabled: true, + + input *telemetryv1beta1.MetricPipeline + + expected *MetricPipeline }, }, + + }{ + + { }, }, + + name: "should convert basic fields", + + input: &telemetryv1beta1.MetricPipeline{ }, }, + + ObjectMeta: metav1.ObjectMeta{ + + Name: "test-pipeline", }, }, + + Namespace: "test-ns", + + }, expected: &telemetryv1beta1.MetricPipeline{ expected: &telemetryv1beta1.MetricPipeline{ + + Spec: telemetryv1beta1.MetricPipelineSpec{}, + + }, Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ + + expected: &MetricPipeline{ + + ObjectMeta: metav1.ObjectMeta{ Input: telemetryv1beta1.MetricPipelineInput{ Input: telemetryv1beta1.MetricPipelineInput{ + + Name: "test-pipeline", + + Namespace: "test-ns", Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ + + }, + + Spec: MetricPipelineSpec{}, Enabled: boolPtr(true), Enabled: true, + + }, + + }, Namespaces: &telemetryv1beta1.NamespaceSelector{ Namespaces: &telemetryv1beta1.NamespaceSelector{ + + { + + name: "should convert namespaces in namespace selectors without validation", Include: []string{"ns1"}, Include: []string{"ns1"}, + + input: &telemetryv1beta1.MetricPipeline{ + + Spec: telemetryv1beta1.MetricPipelineSpec{ }, }, + + Input: telemetryv1beta1.MetricPipelineInput{ + + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ }, }, + + Namespaces: &telemetryv1beta1.NamespaceSelector{ + + Include: []string{"valid-ns", "Invalid_NS"}, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ + + Exclude: []string{"valid-excluded", "Invalid@NS"}, + + }, Enabled: boolPtr(true), Enabled: true, + + }, + + }, Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ + + }, + + }, Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + + expected: &MetricPipeline{ + + Spec: MetricPipelineSpec{ Enabled: boolPtr(true), Enabled: true, + + Input: MetricPipelineInput{ + + Runtime: &MetricPipelineRuntimeInput{ }, }, + + Namespaces: &NamespaceSelector{ + + Include: []string{"valid-ns", "Invalid_NS"}, }, }, + + Exclude: []string{"valid-excluded", "Invalid@NS"}, + + }, }, }, + + }, + + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Istio: &telemetryv1beta1.MetricPipelineIstioInput{ + + }, + + }, Enabled: boolPtr(true), Enabled: true, + + }, + + { DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ + + name: "should convert all input sections", + + input: &telemetryv1beta1.MetricPipeline{ Enabled: boolPtr(true), Enabled: true, + + Spec: telemetryv1beta1.MetricPipelineSpec{ + + Input: telemetryv1beta1.MetricPipelineInput{ }, }, + + Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ + + Enabled: boolPtr(true), }, }, + + Namespaces: &telemetryv1beta1.NamespaceSelector{ + + Include: []string{"ns1"}, OTLP: &telemetryv1beta1.OTLPInput{ OTLP: &telemetryv1beta1.OTLPInput{ + + }, + + }, Disabled: boolPtr(true), Disabled: true, + + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ + + Enabled: boolPtr(true), }, }, + + Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ + + Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ }, }, + + Enabled: boolPtr(true), + + }, }, }, + + }, + + }, }, }, + + Istio: &telemetryv1beta1.MetricPipelineIstioInput{ + + Enabled: boolPtr(true), }, }, + + DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ + + Enabled: boolPtr(true), { { + + }, + + }, name: "should convert output section with authentication", name: "should convert output section with authentication", + + OTLP: &telemetryv1beta1.OTLPInput{ + + Disabled: boolPtr(true), input: &MetricPipeline{ input: &MetricPipeline{ + + }, + + }, Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ + + }, + + }, Output: MetricPipelineOutput{ Output: MetricPipelineOutput{ + + expected: &MetricPipeline{ + + Spec: MetricPipelineSpec{ OTLP: &OTLPOutput{ OTLP: &OTLPOutput{ + + Input: MetricPipelineInput{ + + Prometheus: &MetricPipelinePrometheusInput{ Protocol: "grpc", Protocol: "grpc", + + Enabled: boolPtr(true), + + Namespaces: &NamespaceSelector{ Endpoint: ValueType{ Endpoint: ValueType{ + + Include: []string{"ns1"}, + + }, Value: "localhost:4317", Value: "localhost:4317", + + }, + + Runtime: &MetricPipelineRuntimeInput{ }, }, + + Enabled: boolPtr(true), + + Resources: &MetricPipelineRuntimeInputResources{ Authentication: &AuthenticationOptions{ Authentication: &AuthenticationOptions{ + + Pod: &MetricPipelineRuntimeInputResource{ + + Enabled: boolPtr(true), Basic: &BasicAuthOptions{ Basic: &BasicAuthOptions{ + + }, + + }, User: ValueType{ User: ValueType{ + + }, + + Istio: &MetricPipelineIstioInput{ Value: "user", Value: "user", + + Enabled: boolPtr(true), + + DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ }, }, + + Enabled: boolPtr(true), + + }, Password: ValueType{ Password: ValueType{ + + }, + + OTLP: &OTLPInput{ Value: "pass", Value: "pass", + + Disabled: boolPtr(true), + + }, }, }, + + }, + + }, }, }, + + }, + + }, }, }, + + { + + name: "should convert output section with TLS", }, }, + + input: &telemetryv1beta1.MetricPipeline{ + + Spec: telemetryv1beta1.MetricPipelineSpec{ }, }, + + Output: telemetryv1beta1.MetricPipelineOutput{ + + OTLP: &telemetryv1beta1.OTLPOutput{ }, }, + + Protocol: "grpc", + + Endpoint: telemetryv1beta1.ValueType{ }, }, + + Value: "localhost:4317", + + }, expected: &telemetryv1beta1.MetricPipeline{ expected: &telemetryv1beta1.MetricPipeline{ + + TLS: &telemetryv1beta1.OutputTLS{ + + Disabled: true, Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ + + CA: &telemetryv1beta1.ValueType{ + + Value: "ca-cert", Output: telemetryv1beta1.MetricPipelineOutput{ Output: telemetryv1beta1.MetricPipelineOutput{ + + }, + + Cert: &telemetryv1beta1.ValueType{ OTLP: &telemetryv1beta1.OTLPOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ + + Value: "cert", + + }, Protocol: "grpc", Protocol: "grpc", + + Key: &telemetryv1beta1.ValueType{ + + Value: "key", Endpoint: telemetryv1beta1.ValueType{ Endpoint: telemetryv1beta1.ValueType{ + + }, + + }, Value: "localhost:4317", Value: "localhost:4317", + + }, + + }, }, }, + + }, + + }, Authentication: &telemetryv1beta1.AuthenticationOptions{ Authentication: &telemetryv1beta1.AuthenticationOptions{ + + expected: &MetricPipeline{ + + Spec: MetricPipelineSpec{ Basic: &telemetryv1beta1.BasicAuthOptions{ Basic: &telemetryv1beta1.BasicAuthOptions{ + + Output: MetricPipelineOutput{ + + OTLP: &OTLPOutput{ User: telemetryv1beta1.ValueType{ User: telemetryv1beta1.ValueType{ + + Protocol: "grpc", + + Endpoint: ValueType{ Value: "user", Value: "user", + + Value: "localhost:4317", + + }, }, }, + + TLS: &OTLPTLS{ + + Insecure: true, Password: telemetryv1beta1.ValueType{ Password: telemetryv1beta1.ValueType{ + + CA: &ValueType{ + + Value: "ca-cert", Value: "pass", Value: "pass", + + }, + + Cert: &ValueType{ }, }, + + Value: "cert", + + }, }, }, + + Key: &ValueType{ + + Value: "key", }, }, + + }, + + }, }, }, + + }, + + }, }, }, + + }, + + }, }, }, + + }, + + } }, }, + + + + for _, tt := range tests { }, }, + + t.Run(tt.name, func(t *testing.T) { + + dst := &MetricPipeline{} } } + + err := dst.ConvertFrom(tt.input) + + assert.NoError(t, err) + + assert.Equal(t, tt.expected, dst) + + }) for _, tt := range tests { for _, tt := range tests { + + } + +} t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) { + + + +func TestMetricPipelineConvertToInvalidType(t *testing.T) { dst := &telemetryv1beta1.MetricPipeline{} dst := &telemetryv1beta1.MetricPipeline{} + + src := &MetricPipeline{} + + dst := &MetricPipeline{} // Wrong type, should be v1beta1.MetricPipeline err := tt.input.ConvertTo(dst) err := tt.input.ConvertTo(dst) + + err := src.ConvertTo(dst) + + assert.Error(t, err) assert.NoError(t, err) assert.NoError(t, err) + + assert.Equal(t, errDstTypeUnsupported, err) + +} assert.Equal(t, tt.expected, dst) assert.Equal(t, tt.expected, dst) + + }) }) + + } } + +}} + + + +func TestMetricPipelineConvertFrom(t *testing.T) {func TestMetricPipelineConvertFrom(t *testing.T) { + + tests := []struct { tests := []struct { + + name string name string + + input *telemetryv1beta1.MetricPipeline input *telemetryv1beta1.MetricPipeline + + expected *MetricPipeline expected *MetricPipeline + + }{ }{ + + { { + + name: "should convert basic fields", name: "should convert basic fields", + + input: &telemetryv1beta1.MetricPipeline{ input: &telemetryv1beta1.MetricPipeline{ + + ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ + + Name: "test-pipeline", Name: "test-pipeline", + + Namespace: "test-ns", Namespace: "test-ns", + + }, }, + + Spec: telemetryv1beta1.MetricPipelineSpec{}, Spec: telemetryv1beta1.MetricPipelineSpec{}, + + }, }, + + expected: &MetricPipeline{ expected: &MetricPipeline{ + + ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ + + Name: "test-pipeline", Name: "test-pipeline", + + Namespace: "test-ns", Namespace: "test-ns", + + }, }, + + Spec: MetricPipelineSpec{}, Spec: MetricPipelineSpec{}, + + }, }, + + }, }, + + { { + + name: "should convert namespaces in namespace selectors without validation", name: "should convert namespaces in namespace selectors without validation", + + input: &telemetryv1beta1.MetricPipeline{ input: &telemetryv1beta1.MetricPipeline{ + + Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ + + Input: telemetryv1beta1.MetricPipelineInput{ Input: telemetryv1beta1.MetricPipelineInput{ + + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ + + Namespaces: &telemetryv1beta1.NamespaceSelector{ Namespaces: &telemetryv1beta1.NamespaceSelector{ + + Include: []string{"valid-ns", "Invalid_NS"}, Include: []string{"valid-ns", "Invalid_NS"}, + + Exclude: []string{"valid-excluded", "Invalid@NS"}, Exclude: []string{"valid-excluded", "Invalid@NS"}, + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + expected: &MetricPipeline{ expected: &MetricPipeline{ + + Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ + + Input: MetricPipelineInput{ Input: MetricPipelineInput{ + + Runtime: &MetricPipelineRuntimeInput{ Runtime: &MetricPipelineRuntimeInput{ + + Namespaces: &NamespaceSelector{ Namespaces: &NamespaceSelector{ + + Include: []string{"valid-ns", "Invalid_NS"}, Include: []string{"valid-ns", "Invalid_NS"}, + + Exclude: []string{"valid-excluded", "Invalid@NS"}, Exclude: []string{"valid-excluded", "Invalid@NS"}, + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + { { + + name: "should convert all input sections", name: "should convert all input sections", + + input: &telemetryv1beta1.MetricPipeline{ input: &telemetryv1beta1.MetricPipeline{ + + Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ + + Input: telemetryv1beta1.MetricPipelineInput{ Input: telemetryv1beta1.MetricPipelineInput{ + + Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ + + Enabled: boolPtr(true), Enabled: true, + + Namespaces: &telemetryv1beta1.NamespaceSelector{ Namespaces: &telemetryv1beta1.NamespaceSelector{ + + Include: []string{"ns1"}, Include: []string{"ns1"}, + + }, }, + + }, }, + + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ + + Enabled: boolPtr(true), Enabled: true, + + Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ + + Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + + Enabled: boolPtr(true), Enabled: true, + + }, }, + + }, }, + + }, }, + + Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Istio: &telemetryv1beta1.MetricPipelineIstioInput{ + + Enabled: boolPtr(true), Enabled: true, + + DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ + + Enabled: boolPtr(true), Enabled: true, + + }, }, + + }, }, + + OTLP: &telemetryv1beta1.OTLPInput{ OTLP: &telemetryv1beta1.OTLPInput{ + + Disabled: boolPtr(true), Disabled: true, + + }, }, + + }, }, + + }, }, + + }, }, + + expected: &MetricPipeline{ expected: &MetricPipeline{ + + Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ + + Input: MetricPipelineInput{ Input: MetricPipelineInput{ + + Prometheus: &MetricPipelinePrometheusInput{ Prometheus: &MetricPipelinePrometheusInput{ + + Enabled: boolPtr(true), Enabled: true, + + Namespaces: &NamespaceSelector{ Namespaces: &NamespaceSelector{ + + Include: []string{"ns1"}, Include: []string{"ns1"}, + + }, }, + + }, }, + + Runtime: &MetricPipelineRuntimeInput{ Runtime: &MetricPipelineRuntimeInput{ + + Enabled: boolPtr(true), Enabled: true, + + Resources: &MetricPipelineRuntimeInputResources{ Resources: &MetricPipelineRuntimeInputResources{ + + Pod: &MetricPipelineRuntimeInputResource{ Pod: &MetricPipelineRuntimeInputResource{ + + Enabled: boolPtr(true), Enabled: true, + + }, }, + + }, }, + + }, }, + + Istio: &MetricPipelineIstioInput{ Istio: &MetricPipelineIstioInput{ + + Enabled: boolPtr(true), Enabled: true, + + DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ + + Enabled: boolPtr(true), Enabled: true, + + }, }, + + }, }, + + OTLP: &OTLPInput{ OTLP: &OTLPInput{ + + Disabled: boolPtr(true), Disabled: true, + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + { { + + name: "should convert output section with TLS", name: "should convert output section with TLS", + + input: &telemetryv1beta1.MetricPipeline{ input: &telemetryv1beta1.MetricPipeline{ + + Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ + + Output: telemetryv1beta1.MetricPipelineOutput{ Output: telemetryv1beta1.MetricPipelineOutput{ + + OTLP: &telemetryv1beta1.OTLPOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ + + Protocol: "grpc", Protocol: "grpc", + + Endpoint: telemetryv1beta1.ValueType{ Endpoint: telemetryv1beta1.ValueType{ + + Value: "localhost:4317", Value: "localhost:4317", + + }, }, + + TLS: &telemetryv1beta1.OutputTLS{ TLS: &telemetryv1beta1.OutputTLS{ + + Disabled: true, Disabled: true, + + CA: &telemetryv1beta1.ValueType{ CA: &telemetryv1beta1.ValueType{ + + Value: "ca-cert", Value: "ca-cert", + + }, }, + + Cert: &telemetryv1beta1.ValueType{ Cert: &telemetryv1beta1.ValueType{ + + Value: "cert", Value: "cert", + + }, }, + + Key: &telemetryv1beta1.ValueType{ Key: &telemetryv1beta1.ValueType{ + + Value: "key", Value: "key", + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + expected: &MetricPipeline{ expected: &MetricPipeline{ + + Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ + + Output: MetricPipelineOutput{ Output: MetricPipelineOutput{ + + OTLP: &OTLPOutput{ OTLP: &OTLPOutput{ + + Protocol: "grpc", Protocol: "grpc", + + Endpoint: ValueType{ Endpoint: ValueType{ + + Value: "localhost:4317", Value: "localhost:4317", + + }, }, + + TLS: &OTLPTLS{ TLS: &OTLPTLS{ + + Insecure: true, Insecure: true, + + CA: &ValueType{ CA: &ValueType{ + + Value: "ca-cert", Value: "ca-cert", + + }, }, + + Cert: &ValueType{ Cert: &ValueType{ + + Value: "cert", Value: "cert", + + }, }, + + Key: &ValueType{ Key: &ValueType{ + + Value: "key", Value: "key", + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + }, }, + + } } + + + + for _, tt := range tests { for _, tt := range tests { + + t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) { + + dst := &MetricPipeline{} dst := &MetricPipeline{} + + err := dst.ConvertFrom(tt.input) err := dst.ConvertFrom(tt.input) + + assert.NoError(t, err) assert.NoError(t, err) + + assert.Equal(t, tt.expected, dst) assert.Equal(t, tt.expected, dst) + + }) }) + + } } + +}} + + + +func TestMetricPipelineConvertToInvalidType(t *testing.T) {func TestMetricPipelineConvertToInvalidType(t *testing.T) { + + src := &MetricPipeline{} src := &MetricPipeline{} + + dst := &MetricPipeline{} // Wrong type, should be v1beta1.MetricPipeline dst := &MetricPipeline{} // Wrong type, should be v1beta1.MetricPipeline + + err := src.ConvertTo(dst) err := src.ConvertTo(dst) + + assert.Error(t, err) assert.Error(t, err) + + assert.Equal(t, errDstTypeUnsupported, err) assert.Equal(t, errDstTypeUnsupported, err) + +}} \ No newline at end of file diff --git a/apis/telemetry/v1alpha1/shared_types_conversion.go b/apis/telemetry/v1alpha1/shared_types_conversion.go new file mode 100644 index 0000000000..8849fd42db --- /dev/null +++ b/apis/telemetry/v1alpha1/shared_types_conversion.go @@ -0,0 +1,30 @@ +package v1alpha1 + +import ( + "regexp" + + telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" +) + +// Remove invalid namespace names from NamespaceSelector slices (include/exclude) +func sanitizeNamespaceNames(names []string) []string { + var valid []string + // Kubernetes namespace regex + var nsRegex = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`) + for _, n := range names { + if len(n) <= 63 && nsRegex.MatchString(n) { + valid = append(valid, n) + } + } + return valid +} + +func convertNamespaceSelectorToBeta(ns *NamespaceSelector) *telemetryv1beta1.NamespaceSelector { + if ns == nil { + return nil + } + return &telemetryv1beta1.NamespaceSelector{ + Include: sanitizeNamespaceNames(ns.Include), + Exclude: sanitizeNamespaceNames(ns.Exclude), + } +} diff --git a/apis/telemetry/v1beta1/metricpipeline_conversion.go b/apis/telemetry/v1beta1/metricpipeline_conversion.go new file mode 100644 index 0000000000..89567cf491 --- /dev/null +++ b/apis/telemetry/v1beta1/metricpipeline_conversion.go @@ -0,0 +1,5 @@ +package v1beta1 + +// Hub marks this type as a conversion hub. +func (lp *MetricPipeline) Hub() { +} diff --git a/internal/webhookcert/resources.go b/internal/webhookcert/resources.go index 13da1b39bc..a8bf3d8d9a 100644 --- a/internal/webhookcert/resources.go +++ b/internal/webhookcert/resources.go @@ -17,8 +17,9 @@ const ( // applyWebhookConfigResources applies the following webhook configurations: // 1- Updates validating webhook configuration with the provided CA bundle. -// 2- Updates LogPipeline CRD with conversion webhook configuration. -// 3- Updates mutating webhook configuration with the provided CA bundle. +// 2- Updates mutating webhook configuration with the provided CA bundle. +// 3- Updates LogPipeline CRD with conversion webhook configuration. +// 4- Updates MetricPipeline CRD with conversion webhook configuration. func applyWebhookConfigResources(ctx context.Context, c client.Client, caBundle []byte, config Config) error { if err := updateValidatingWebhookConfig(ctx, c, caBundle, config); err != nil { return fmt.Errorf("failed to update validating webhook with CA bundle: %w", err) @@ -29,10 +30,14 @@ func applyWebhookConfigResources(ctx context.Context, c client.Client, caBundle } conversionWebhookConfig := makeConversionWebhookConfig(caBundle, config) - if err := updateLogPipelineCRDWithConversionWebhookConfig(ctx, c, conversionWebhookConfig); err != nil { + if err := updatePipelineCRDWithConversionWebhookConfig(ctx, c, types.NamespacedName{Name: "logpipelines.telemetry.kyma-project.io"}, conversionWebhookConfig); err != nil { return fmt.Errorf("failed to update LogPipeline CRD with conversion webhook configuration: %w", err) } + if err := updatePipelineCRDWithConversionWebhookConfig(ctx, c, types.NamespacedName{Name: "metricpipelines.telemetry.kyma-project.io"}, conversionWebhookConfig); err != nil { + return fmt.Errorf("failed to update MetricPipeline CRD with conversion webhook configuration: %w", err) + } + return nil } @@ -67,15 +72,15 @@ func makeConversionWebhookConfig(caBundle []byte, config Config) apiextensionsv1 } } -func updateLogPipelineCRDWithConversionWebhookConfig(ctx context.Context, c client.Client, conversion apiextensionsv1.CustomResourceConversion) error { - var logPipelineCRD apiextensionsv1.CustomResourceDefinition - if err := c.Get(ctx, types.NamespacedName{Name: "logpipelines.telemetry.kyma-project.io"}, &logPipelineCRD); err != nil { +func updatePipelineCRDWithConversionWebhookConfig(ctx context.Context, c client.Client, pipelineType types.NamespacedName, conversion apiextensionsv1.CustomResourceConversion) error { + var crd apiextensionsv1.CustomResourceDefinition + if err := c.Get(ctx, pipelineType, &crd); err != nil { return fmt.Errorf("failed to get logpipelines CRD: %w", err) } - logPipelineCRD.Spec.Conversion = &conversion + crd.Spec.Conversion = &conversion - return c.Update(ctx, &logPipelineCRD) + return c.Update(ctx, &crd) } func updateMutatingWebhookConfig(ctx context.Context, c client.Client, caBundle []byte, config Config) error { diff --git a/main.go b/main.go index f75b7bf8c0..9553134bd3 100644 --- a/main.go +++ b/main.go @@ -396,7 +396,6 @@ func setupLogPipelineController(mgr manager.Manager, reconcileTriggerChan <-chan if featureflags.IsEnabled(featureflags.V1Beta1) { setupLog.Info("Registering conversion webhooks for LogPipelines") utilruntime.Must(telemetryv1beta1.AddToScheme(scheme)) - // Register conversion webhooks for LogPipelines if err := ctrl.NewWebhookManagedBy(mgr). For(&telemetryv1alpha1.LogPipeline{}). Complete(); err != nil { @@ -408,6 +407,19 @@ func setupLogPipelineController(mgr manager.Manager, reconcileTriggerChan <-chan Complete(); err != nil { return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) } + + setupLog.Info("Registering conversion webhooks for MetricPipelines") + if err := ctrl.NewWebhookManagedBy(mgr). + For(&telemetryv1alpha1.MetricPipeline{}). + Complete(); err != nil { + return fmt.Errorf("failed to create v1alpha1 conversion webhook: %w", err) + } + + if err := ctrl.NewWebhookManagedBy(mgr). + For(&telemetryv1beta1.MetricPipeline{}). + Complete(); err != nil { + return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) + } } setupLog.Info("Setting up logpipeline controller") From cf57e307f493b2076efadff8c77ff4d7de2fc510 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Fri, 17 Oct 2025 18:59:36 +0200 Subject: [PATCH 02/27] fix --- .../v1alpha1/logpipeline_conversion.go | 369 +---- .../v1alpha1/logpipeline_conversion_test.go | 763 +++++---- .../v1alpha1/metricpipeline_conversion.go | 264 +--- .../metricpipeline_conversion_test.go | 1372 +++-------------- .../v1alpha1/shared_types_conversion.go | 262 ++++ apis/telemetry/v1beta1/logpipeline_types.go | 4 +- .../telemetry/v1beta1/metricpipeline_types.go | 2 +- apis/telemetry/v1beta1/shared_types.go | 4 +- .../v1beta1/zz_generated.deepcopy.go | 15 +- ...elemetry.kyma-project.io_logpipelines.yaml | 30 +- ...metry.kyma-project.io_metricpipelines.yaml | 4 +- internal/utils/test/log_pipeline_builder.go | 4 +- main.go | 2 + .../shared/single_pipeline_v1beta1_test.go | 4 +- webhook/logpipeline/v1beta1/defaulter.go | 15 + webhook/logpipeline/v1beta1/defaulter_test.go | 35 + webhook/logpipeline/v1beta1/setup.go | 2 + webhook/metricpipeline/v1beta1/defaulter.go | 9 + .../metricpipeline/v1beta1/defaulter_test.go | 54 + webhook/metricpipeline/v1beta1/setup.go | 1 + 20 files changed, 1175 insertions(+), 2040 deletions(-) diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index b44b14a139..59d7f82f7c 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -3,13 +3,14 @@ package v1alpha1 import ( "errors" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/conversion" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" ) -var errSrcTypeUnsupported = errors.New("source type is not LogPipeline v1alpha1") -var errDstTypeUnsupported = errors.New("destination type is not LogPipeline v1beta1") +var errSrcTypeUnsupportedLogPipeline = errors.New("source type is not LogPipeline v1alpha1") +var errDstTypeUnsupportedLogPipeline = errors.New("destination type is not LogPipeline v1beta1") // ConvertTo converts this LogPipeline to the Hub version (v1alpha1 -> v1beta1). func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { @@ -17,14 +18,22 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { dst, ok := dstRaw.(*telemetryv1beta1.LogPipeline) if !ok { - return errDstTypeUnsupported + return errDstTypeUnsupportedLogPipeline } + // Copy metadata dst.ObjectMeta = src.ObjectMeta + // Copy Spec fields dst.Spec.Input = telemetryv1beta1.LogPipelineInput{} - dst.Spec.Input.Runtime = v1Alpha1ApplicationToV1Beta1(src.Spec.Input.Application) - dst.Spec.Input.OTLP = v1Alpha1OTLPInputToV1Beta1(src.Spec.Input.OTLP) + dst.Spec.Input.Runtime = convertApplicationToBeta(src.Spec.Input.Application) + + if src.Spec.Input.OTLP != nil { + dst.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(!src.Spec.Input.OTLP.Disabled), + Namespaces: convertNamespaceSelectorToBeta(src.Spec.Input.OTLP.Namespaces), + } + } for _, f := range src.Spec.Files { dst.Spec.Files = append(dst.Spec.Files, telemetryv1beta1.LogPipelineFileMount(f)) @@ -36,35 +45,28 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { if srcHTTPOutput := src.Spec.Output.HTTP; srcHTTPOutput != nil { dst.Spec.Output.HTTP = &telemetryv1beta1.LogPipelineHTTPOutput{ - Host: v1Alpha1ValueTypeToV1Beta1(srcHTTPOutput.Host), + Host: convertValueTypeToBeta(srcHTTPOutput.Host), URI: srcHTTPOutput.URI, Port: srcHTTPOutput.Port, Compress: srcHTTPOutput.Compress, Format: srcHTTPOutput.Format, - TLSConfig: v1Alpha1TLSToV1Beta1(srcHTTPOutput.TLS), + TLSConfig: convertOutputTLSToBeta(srcHTTPOutput.TLS), Dedot: srcHTTPOutput.Dedot, } if srcHTTPOutput.User != nil && (srcHTTPOutput.User.Value != "" || srcHTTPOutput.User.ValueFrom != nil) { - user := v1Alpha1ValueTypeToV1Beta1(*srcHTTPOutput.User) + user := convertValueTypeToBeta(*srcHTTPOutput.User) dst.Spec.Output.HTTP.User = &user } if srcHTTPOutput.Password != nil && (srcHTTPOutput.Password.Value != "" || srcHTTPOutput.Password.ValueFrom != nil) { - password := v1Alpha1ValueTypeToV1Beta1(*srcHTTPOutput.Password) + password := convertValueTypeToBeta(*srcHTTPOutput.Password) dst.Spec.Output.HTTP.Password = &password } } - if srcOTLPOutput := src.Spec.Output.OTLP; srcOTLPOutput != nil { - dst.Spec.Output.OTLP = &telemetryv1beta1.OTLPOutput{ - Protocol: telemetryv1beta1.OTLPProtocol(srcOTLPOutput.Protocol), - Endpoint: v1Alpha1ValueTypeToV1Beta1(srcOTLPOutput.Endpoint), - Path: srcOTLPOutput.Path, - Authentication: v1Alpha1AuthenticationToV1Beta1(srcOTLPOutput.Authentication), - Headers: v1Alpha1HeadersToV1Beta1(srcOTLPOutput.Headers), - TLS: v1Alpha1OTLPTLSToV1Beta1(srcOTLPOutput.TLS), - } + if src.Spec.Output.OTLP != nil { + dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) } if srcCustomOutput := src.Spec.Output.Custom; srcCustomOutput != "" { @@ -73,13 +75,13 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { if src.Spec.Transforms != nil { for _, t := range src.Spec.Transforms { - dst.Spec.Transforms = append(dst.Spec.Transforms, v1Alpha1TransformSpecToV1Beta1(t)) + dst.Spec.Transforms = append(dst.Spec.Transforms, convertTransformSpecToBeta(t)) } } if src.Spec.Filters != nil { for _, t := range src.Spec.Filters { - dst.Spec.Filters = append(dst.Spec.Filters, v1Alpha1FilterSpecToV1Beta1(t)) + dst.Spec.Filters = append(dst.Spec.Filters, convertFilterSpecToBeta(t)) } } @@ -88,31 +90,23 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { return nil } -func v1Alpha1OTLPInputToV1Beta1(otlp *OTLPInput) *telemetryv1beta1.OTLPInput { - if otlp == nil { +func convertApplicationToBeta(application *LogPipelineApplicationInput) *telemetryv1beta1.LogPipelineRuntimeInput { + if application == nil { return nil } - input := &telemetryv1beta1.OTLPInput{ - Disabled: otlp.Disabled, - } - - input.Namespaces = convertNamespaceSelectorToBeta(otlp.Namespaces) - - return input -} - -func v1Alpha1ApplicationToV1Beta1(application *LogPipelineApplicationInput) *telemetryv1beta1.LogPipelineRuntimeInput { - if application == nil { - return nil + var excludes []string + if len(application.Namespaces.Include) == 0 && len(application.Namespaces.Exclude) == 0 && !application.Namespaces.System { + excludes = []string{"kyma-system", "kube-system", "istio-system", "compass-system"} + } else { + excludes = application.Namespaces.Exclude } runtime := &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: application.Enabled, - Namespaces: telemetryv1beta1.LogPipelineNamespaceSelector{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ Include: sanitizeNamespaceNames(application.Namespaces.Include), - Exclude: sanitizeNamespaceNames(application.Namespaces.Exclude), - System: application.Namespaces.System, + Exclude: sanitizeNamespaceNames(excludes), }, Containers: telemetryv1beta1.LogPipelineContainerSelector{ Include: application.Containers.Include, @@ -126,141 +120,39 @@ func v1Alpha1ApplicationToV1Beta1(application *LogPipelineApplicationInput) *tel return runtime } -func v1Alpha1OTLPTLSToV1Beta1(tls *OTLPTLS) *telemetryv1beta1.OutputTLS { - if tls == nil { - return nil - } - - betaTLS := &telemetryv1beta1.OutputTLS{ - Disabled: tls.Insecure, - SkipCertificateValidation: tls.InsecureSkipVerify, - } - - if tls.CA != nil { - ca := v1Alpha1ValueTypeToV1Beta1(*tls.CA) - betaTLS.CA = &ca - } - - if tls.Key != nil { - key := v1Alpha1ValueTypeToV1Beta1(*tls.Key) - betaTLS.Key = &key - } - - if tls.Cert != nil { - cert := v1Alpha1ValueTypeToV1Beta1(*tls.Cert) - betaTLS.Cert = &cert - } - - return betaTLS -} - -func v1Alpha1HeadersToV1Beta1(headers []Header) []telemetryv1beta1.Header { - var dst []telemetryv1beta1.Header - for _, h := range headers { - dst = append(dst, v1Alpha1HeaderToV1Beta1(h)) - } - - return dst -} - -func v1Alpha1HeaderToV1Beta1(h Header) telemetryv1beta1.Header { - return telemetryv1beta1.Header{ - Name: h.Name, - ValueType: v1Alpha1ValueTypeToV1Beta1(h.ValueType), - Prefix: h.Prefix, - } -} - -func v1Alpha1AuthenticationToV1Beta1(authentication *AuthenticationOptions) *telemetryv1beta1.AuthenticationOptions { - if authentication == nil { - return nil - } - - return &telemetryv1beta1.AuthenticationOptions{ - Basic: v1Alpha1BasicAuthOptionsToV1Beta1(authentication.Basic), - } -} - -func v1Alpha1BasicAuthOptionsToV1Beta1(basic *BasicAuthOptions) *telemetryv1beta1.BasicAuthOptions { - if basic == nil { - return nil - } - - return &telemetryv1beta1.BasicAuthOptions{ - User: v1Alpha1ValueTypeToV1Beta1(basic.User), - Password: v1Alpha1ValueTypeToV1Beta1(basic.Password), - } -} - -func v1Alpha1ValueTypeToV1Beta1(src ValueType) telemetryv1beta1.ValueType { - if src.ValueFrom != nil && src.ValueFrom.SecretKeyRef != nil { - return telemetryv1beta1.ValueType{ - ValueFrom: &telemetryv1beta1.ValueFromSource{ - SecretKeyRef: (*telemetryv1beta1.SecretKeyRef)(src.ValueFrom.SecretKeyRef), - }, - } - } - - return telemetryv1beta1.ValueType{ - Value: src.Value, - } -} - -func v1Alpha1TLSToV1Beta1(src LogPipelineOutputTLS) telemetryv1beta1.OutputTLS { +func convertOutputTLSToBeta(src LogPipelineOutputTLS) telemetryv1beta1.OutputTLS { var dst telemetryv1beta1.OutputTLS - if src.CA != nil { - ca := v1Alpha1ValueTypeToV1Beta1(*src.CA) - dst.CA = &ca - } - - if src.Cert != nil { - cert := v1Alpha1ValueTypeToV1Beta1(*src.Cert) - dst.Cert = &cert - } - - if src.Key != nil { - key := v1Alpha1ValueTypeToV1Beta1(*src.Key) - dst.Key = &key - } - + dst.CA = convertValueTypeToBetaPtr(src.CA) + dst.Cert = convertValueTypeToBetaPtr(src.Cert) + dst.Key = convertValueTypeToBetaPtr(src.Key) dst.Disabled = src.Disabled dst.SkipCertificateValidation = src.SkipCertificateValidation return dst } -func v1Alpha1TransformSpecToV1Beta1(src TransformSpec) telemetryv1beta1.TransformSpec { - var dst telemetryv1beta1.TransformSpec - - dst.Conditions = append(dst.Conditions, src.Conditions...) - - dst.Statements = append(dst.Statements, src.Statements...) - - return dst -} - -func v1Alpha1FilterSpecToV1Beta1(src FilterSpec) telemetryv1beta1.FilterSpec { - var dst telemetryv1beta1.FilterSpec - - dst.Conditions = append(dst.Conditions, src.Conditions...) - - return dst -} - // ConvertFrom converts from the Hub version (v1beta1 -> v1alpha1) to this version. func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { dst := lp src, ok := srcRaw.(*telemetryv1beta1.LogPipeline) if !ok { - return errSrcTypeUnsupported + return errSrcTypeUnsupportedLogPipeline } + // Copy metadata dst.ObjectMeta = src.ObjectMeta - dst.Spec.Input.Application = v1Beta1RuntimeToV1Alpha1(src.Spec.Input.Runtime) - dst.Spec.Input.OTLP = v1Beta1OTLPInputToV1Alpha1(src.Spec.Input.OTLP) + // Copy Spec fields + dst.Spec.Input.Application = convertRuntimeToAlpha(src.Spec.Input.Runtime) + + if src.Spec.Input.OTLP != nil { + dst.Spec.Input.OTLP = &OTLPInput{ + Disabled: src.Spec.Input.OTLP.Enabled != nil && !*src.Spec.Input.OTLP.Enabled, + Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.OTLP.Namespaces), + } + } for _, f := range src.Spec.Files { dst.Spec.Files = append(dst.Spec.Files, LogPipelineFileMount(f)) @@ -272,35 +164,21 @@ func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { if srcHTTPOutput := src.Spec.Output.HTTP; srcHTTPOutput != nil { dst.Spec.Output.HTTP = &LogPipelineHTTPOutput{ - Host: v1Beta1ValueTypeToV1Alpha1(srcHTTPOutput.Host), + Host: convertValueTypeToAlpha(srcHTTPOutput.Host), URI: srcHTTPOutput.URI, Port: srcHTTPOutput.Port, Compress: srcHTTPOutput.Compress, Format: srcHTTPOutput.Format, - TLS: v1Beta1TLSToV1Alpha1(srcHTTPOutput.TLSConfig), + TLS: convertOutputTLSToAlpha(srcHTTPOutput.TLSConfig), Dedot: srcHTTPOutput.Dedot, } - if srcHTTPOutput.User != nil { - user := v1Beta1ValueTypeToV1Alpha1(*srcHTTPOutput.User) - dst.Spec.Output.HTTP.User = &user - } - - if srcHTTPOutput.Password != nil { - password := v1Beta1ValueTypeToV1Alpha1(*srcHTTPOutput.Password) - dst.Spec.Output.HTTP.Password = &password - } + dst.Spec.Output.HTTP.User = convertValueTypeToAlphaPtr(srcHTTPOutput.User) + dst.Spec.Output.HTTP.Password = convertValueTypeToAlphaPtr(srcHTTPOutput.Password) } - if srcOTLPOutput := src.Spec.Output.OTLP; srcOTLPOutput != nil { - dst.Spec.Output.OTLP = &OTLPOutput{ - Protocol: (string)(srcOTLPOutput.Protocol), - Endpoint: v1Beta1ValueTypeToV1Alpha1(srcOTLPOutput.Endpoint), - Path: srcOTLPOutput.Path, - Authentication: v1Beta1AuthenticationToV1Alpha1(srcOTLPOutput.Authentication), - Headers: v1Beta1HeadersToV1Alpha1(srcOTLPOutput.Headers), - TLS: v1Beta1OTLPTLSToV1Alpha1(srcOTLPOutput.TLS), - } + if src.Spec.Output.OTLP != nil { + dst.Spec.Output.OTLP = convertOTLPOutputToAlpha(src.Spec.Output.OTLP) } if srcCustomOutput := src.Spec.Output.Custom; srcCustomOutput != "" { @@ -309,13 +187,13 @@ func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { if src.Spec.Transforms != nil { for _, t := range src.Spec.Transforms { - dst.Spec.Transforms = append(dst.Spec.Transforms, v1Beta1TransformSpecToV1Alpha1(t)) + dst.Spec.Transforms = append(dst.Spec.Transforms, convertTransformSpecToAlpha(t)) } } if src.Spec.Filters != nil { for _, t := range src.Spec.Filters { - dst.Spec.Filters = append(dst.Spec.Filters, v1Beta1FilterSpecToV1Alpha1(t)) + dst.Spec.Filters = append(dst.Spec.Filters, convertFilterSpecToAlpha(t)) } } @@ -324,7 +202,7 @@ func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { return nil } -func v1Beta1RuntimeToV1Alpha1(runtime *telemetryv1beta1.LogPipelineRuntimeInput) *LogPipelineApplicationInput { +func convertRuntimeToAlpha(runtime *telemetryv1beta1.LogPipelineRuntimeInput) *LogPipelineApplicationInput { if runtime == nil { return nil } @@ -334,7 +212,7 @@ func v1Beta1RuntimeToV1Alpha1(runtime *telemetryv1beta1.LogPipelineRuntimeInput) Namespaces: LogPipelineNamespaceSelector{ Include: runtime.Namespaces.Include, Exclude: runtime.Namespaces.Exclude, - System: runtime.Namespaces.System, + System: false, }, Containers: LogPipelineContainerSelector{ Include: runtime.Containers.Include, @@ -348,142 +226,15 @@ func v1Beta1RuntimeToV1Alpha1(runtime *telemetryv1beta1.LogPipelineRuntimeInput) return application } -func v1Beta1OTLPInputToV1Alpha1(otlp *telemetryv1beta1.OTLPInput) *OTLPInput { - if otlp == nil { - return nil - } - - input := &OTLPInput{ - Disabled: otlp.Disabled, - } - if otlp.Namespaces != nil { - input.Namespaces = &NamespaceSelector{ - Include: otlp.Namespaces.Include, - Exclude: otlp.Namespaces.Exclude, - } - } - - return input -} - -func v1Beta1OTLPTLSToV1Alpha1(tls *telemetryv1beta1.OutputTLS) *OTLPTLS { - if tls == nil { - return nil - } - - alphaTLS := &OTLPTLS{ - Insecure: tls.Disabled, - InsecureSkipVerify: tls.SkipCertificateValidation, - } - - if tls.CA != nil { - ca := v1Beta1ValueTypeToV1Alpha1(*tls.CA) - alphaTLS.CA = &ca - } - - if tls.Key != nil { - key := v1Beta1ValueTypeToV1Alpha1(*tls.Key) - alphaTLS.Key = &key - } - - if tls.Cert != nil { - cert := v1Beta1ValueTypeToV1Alpha1(*tls.Cert) - alphaTLS.Cert = &cert - } - - return alphaTLS -} - -func v1Beta1HeadersToV1Alpha1(headers []telemetryv1beta1.Header) []Header { - var dst []Header - for _, h := range headers { - dst = append(dst, v1Beta1HeaderToV1Alpha1(h)) - } - - return dst -} - -func v1Beta1HeaderToV1Alpha1(h telemetryv1beta1.Header) Header { - return Header{ - Name: h.Name, - ValueType: v1Beta1ValueTypeToV1Alpha1(h.ValueType), - Prefix: h.Prefix, - } -} - -func v1Beta1AuthenticationToV1Alpha1(authentication *telemetryv1beta1.AuthenticationOptions) *AuthenticationOptions { - if authentication == nil { - return nil - } - - return &AuthenticationOptions{ - Basic: v1Beta1BasicAuthOptionsToV1Alpha1(authentication.Basic), - } -} - -func v1Beta1BasicAuthOptionsToV1Alpha1(basic *telemetryv1beta1.BasicAuthOptions) *BasicAuthOptions { - if basic == nil { - return nil - } - - return &BasicAuthOptions{ - User: v1Beta1ValueTypeToV1Alpha1(basic.User), - Password: v1Beta1ValueTypeToV1Alpha1(basic.Password), - } -} - -func v1Beta1TLSToV1Alpha1(src telemetryv1beta1.OutputTLS) LogPipelineOutputTLS { +func convertOutputTLSToAlpha(src telemetryv1beta1.OutputTLS) LogPipelineOutputTLS { var dst LogPipelineOutputTLS - if src.CA != nil { - ca := v1Beta1ValueTypeToV1Alpha1(*src.CA) - dst.CA = &ca - } - - if src.Cert != nil { - cert := v1Beta1ValueTypeToV1Alpha1(*src.Cert) - dst.Cert = &cert - } - - if src.Key != nil { - key := v1Beta1ValueTypeToV1Alpha1(*src.Key) - dst.Key = &key - } + dst.CA = convertValueTypeToAlphaPtr(src.CA) + dst.Cert = convertValueTypeToAlphaPtr(src.Cert) + dst.Key = convertValueTypeToAlphaPtr(src.Key) dst.Disabled = src.Disabled dst.SkipCertificateValidation = src.SkipCertificateValidation return dst } - -func v1Beta1ValueTypeToV1Alpha1(src telemetryv1beta1.ValueType) ValueType { - if src.ValueFrom != nil && src.ValueFrom.SecretKeyRef != nil { - return ValueType{ - ValueFrom: &ValueFromSource{ - SecretKeyRef: (*SecretKeyRef)(src.ValueFrom.SecretKeyRef), - }, - } - } - - return ValueType{ - Value: src.Value, - } -} - -func v1Beta1TransformSpecToV1Alpha1(src telemetryv1beta1.TransformSpec) TransformSpec { - var dst TransformSpec - - dst.Conditions = append(dst.Conditions, src.Conditions...) - - dst.Statements = append(dst.Statements, src.Statements...) - - return dst -} - -func v1Beta1FilterSpecToV1Alpha1(src telemetryv1beta1.FilterSpec) FilterSpec { - var dst FilterSpec - - dst.Conditions = append(dst.Conditions, src.Conditions...) - - return dst -} diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion_test.go b/apis/telemetry/v1alpha1/logpipeline_conversion_test.go index 2c963626fd..b5d08edc69 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion_test.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion_test.go @@ -3,7 +3,6 @@ package v1alpha1 import ( "testing" - "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" @@ -11,395 +10,501 @@ import ( telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" ) -func TestConvertTo(t *testing.T) { - src := &LogPipeline{ - ObjectMeta: metav1.ObjectMeta{ - Name: "log-pipeline-test", - }, - Spec: LogPipelineSpec{ - Input: LogPipelineInput{ - Application: &LogPipelineApplicationInput{ - Enabled: ptr.To(true), - Namespaces: LogPipelineNamespaceSelector{ - Include: []string{"default", "kube-system"}, - Exclude: []string{"kube-public"}, - System: true, - }, - Containers: LogPipelineContainerSelector{ - Include: []string{"nginx", "app"}, - Exclude: []string{"sidecar"}, - }, - KeepAnnotations: ptr.To(true), - DropLabels: ptr.To(true), - KeepOriginalBody: ptr.To(true), - }, - OTLP: &OTLPInput{ - Disabled: true, - Namespaces: &NamespaceSelector{ - Include: []string{"include", "include2"}, - Exclude: []string{"exclude", "exclude2"}, - }, +var v1alpha1LogPipeline = &LogPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "log-pipeline-test", + }, + Spec: LogPipelineSpec{ + Input: LogPipelineInput{ + Application: &LogPipelineApplicationInput{ + Enabled: ptr.To(true), + Namespaces: LogPipelineNamespaceSelector{ + Include: []string{"default", "kube-system"}, + Exclude: []string{"kube-public"}, + System: false, + }, + Containers: LogPipelineContainerSelector{ + Include: []string{"nginx", "app"}, + Exclude: []string{"sidecar"}, }, + KeepAnnotations: ptr.To(true), + DropLabels: ptr.To(true), + KeepOriginalBody: ptr.To(true), }, - Files: []LogPipelineFileMount{ - {Name: "file1", Content: "file1-content"}, + OTLP: &OTLPInput{ + Disabled: true, + Namespaces: &NamespaceSelector{ + Include: []string{"include", "include2"}, + Exclude: []string{"exclude", "exclude2"}, + }, }, - FluentBitFilters: []LogPipelineFilter{ - {Custom: "name stdout"}, + }, + Files: []LogPipelineFileMount{ + {Name: "file1", Content: "file1-content"}, + }, + FluentBitFilters: []LogPipelineFilter{ + {Custom: "name stdout"}, + }, + Transforms: []TransformSpec{ + { + Conditions: []string{"resource.attributes[\"k8s.pod.name\"] == nil"}, + Statements: []string{"set(resource.attributes[\"k8s.pod.name\"]", "nginx"}, }, - Transforms: []TransformSpec{ - { - Conditions: []string{"resource.attributes[\"k8s.pod.name\"] == nil"}, - Statements: []string{"set(resource.attributes[\"k8s.pod.name\"]", "nginx"}, - }, + }, + Filters: []FilterSpec{ + { + Conditions: []string{"log.time == nil"}, }, - Filters: []FilterSpec{ - { - Conditions: []string{"log.time == nil"}, + }, + Output: LogPipelineOutput{ + Custom: "custom-output", + HTTP: &LogPipelineHTTPOutput{ + Host: ValueType{ + Value: "http://localhost", }, - }, - Output: LogPipelineOutput{ - Custom: "custom-output", - HTTP: &LogPipelineHTTPOutput{ - Host: ValueType{ - Value: "http://localhost", + User: &ValueType{ + Value: "user", + }, + Password: &ValueType{ + ValueFrom: &ValueFromSource{ + SecretKeyRef: &SecretKeyRef{ + Name: "secret-name", + Namespace: "secret-namespace", + Key: "secret-key", + }, }, - User: &ValueType{ - Value: "user", + }, + URI: "/ingest/v1beta1/logs", + Port: "8080", + Compress: "on", + Format: "json", + TLS: LogPipelineOutputTLS{ + SkipCertificateValidation: true, + CA: &ValueType{ + Value: "ca", }, - Password: &ValueType{ - ValueFrom: &ValueFromSource{ - SecretKeyRef: &SecretKeyRef{ - Name: "secret-name", - Namespace: "secret-namespace", - Key: "secret-key", - }, - }, + Cert: &ValueType{ + Value: "cert", }, - URI: "/ingest/v1beta1/logs", - Port: "8080", - Compress: "on", - Format: "json", - TLS: LogPipelineOutputTLS{ - SkipCertificateValidation: true, - CA: &ValueType{ - Value: "ca", - }, - Cert: &ValueType{ - Value: "cert", + Key: &ValueType{ + Value: "key", + }, + }, + Dedot: true, + }, + OTLP: &OTLPOutput{ + Protocol: OTLPProtocolGRPC, + Endpoint: ValueType{ + Value: "localhost:4317", + }, + Path: "/v1/logs", + Authentication: &AuthenticationOptions{ + Basic: &BasicAuthOptions{ + User: ValueType{ + Value: "user", }, - Key: &ValueType{ - Value: "key", + Password: ValueType{ + Value: "password", }, }, - Dedot: true, }, - OTLP: &OTLPOutput{ - Protocol: OTLPProtocolGRPC, - Endpoint: ValueType{ - Value: "localhost:4317", - }, - Path: "/v1/logs", - Authentication: &AuthenticationOptions{ - Basic: &BasicAuthOptions{ - User: ValueType{ - Value: "user", - }, - Password: ValueType{ - Value: "password", - }, + Headers: []Header{ + { + Name: "header1", + ValueType: ValueType{ + Value: "value1", }, + Prefix: "prefix1", }, - Headers: []Header{ - { - Name: "header1", - ValueType: ValueType{ - Value: "value1", - }, - Prefix: "prefix1", - }, - { - Name: "header2", - ValueType: ValueType{ - Value: "value2", - }, - Prefix: "prefix2", + { + Name: "header2", + ValueType: ValueType{ + Value: "value2", }, + Prefix: "prefix2", }, - TLS: &OTLPTLS{ - Insecure: true, - InsecureSkipVerify: true, - CA: &ValueType{ - Value: "ca", - }, - Cert: &ValueType{ - Value: "cert", - }, - Key: &ValueType{ - Value: "key", - }, + }, + TLS: &OTLPTLS{ + Insecure: true, + InsecureSkipVerify: true, + CA: &ValueType{ + Value: "ca", + }, + Cert: &ValueType{ + Value: "cert", + }, + Key: &ValueType{ + Value: "key", }, }, }, }, - Status: LogPipelineStatus{ - Conditions: []metav1.Condition{ - { - Type: "LogAgentHealthy", - Status: "True", - Reason: "FluentBitReady", - Message: "FluentBit is and collecting logs", - }, + }, + Status: LogPipelineStatus{ + Conditions: []metav1.Condition{ + { + Type: "LogAgentHealthy", + Status: "True", + Reason: "FluentBitReady", + Message: "FluentBit is and collecting logs", }, - UnsupportedMode: ptr.To(true), }, - } - - dst := &telemetryv1beta1.LogPipeline{} - - err := src.ConvertTo(dst) - require.NoError(t, err) - - requireLogPipelinesEquivalent(t, src, dst) - - srcAfterRoundTrip := &LogPipeline{} - err = srcAfterRoundTrip.ConvertFrom(dst) - require.NoError(t, err) - require.Empty(t, cmp.Diff(src, srcAfterRoundTrip), "expected source be equal to itself after round-trip") + UnsupportedMode: ptr.To(true), + }, } -func TestConvertFrom(t *testing.T) { - src := &telemetryv1beta1.LogPipeline{ - ObjectMeta: metav1.ObjectMeta{ - Name: "log-pipeline-test", - }, - Spec: telemetryv1beta1.LogPipelineSpec{ - Input: telemetryv1beta1.LogPipelineInput{ - Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ - Enabled: ptr.To(true), - Namespaces: telemetryv1beta1.LogPipelineNamespaceSelector{ - Include: []string{"default", "kube-system"}, - Exclude: []string{"kube-public"}, - System: true, - }, - Containers: telemetryv1beta1.LogPipelineContainerSelector{ - Include: []string{"nginx", "app"}, - Exclude: []string{"sidecar"}, - }, - KeepAnnotations: ptr.To(true), - DropLabels: ptr.To(true), - KeepOriginalBody: ptr.To(true), - }, - OTLP: &telemetryv1beta1.OTLPInput{ - Disabled: true, - Namespaces: &telemetryv1beta1.NamespaceSelector{ - Include: []string{"include", "include2"}, - Exclude: []string{"exclude", "exclude2"}, - }, +var v1beta1LogPipeline = &telemetryv1beta1.LogPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "log-pipeline-test", + }, + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Enabled: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"default", "kube-system"}, + Exclude: []string{"kube-public"}, + }, + Containers: telemetryv1beta1.LogPipelineContainerSelector{ + Include: []string{"nginx", "app"}, + Exclude: []string{"sidecar"}, }, + KeepAnnotations: ptr.To(true), + DropLabels: ptr.To(true), + KeepOriginalBody: ptr.To(true), }, - Files: []telemetryv1beta1.LogPipelineFileMount{ - {Name: "file1", Content: "file1-content"}, + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"include", "include2"}, + Exclude: []string{"exclude", "exclude2"}, + }, }, - FluentBitFilters: []telemetryv1beta1.LogPipelineFilter{ - {Custom: "name stdout"}, + }, + Files: []telemetryv1beta1.LogPipelineFileMount{ + {Name: "file1", Content: "file1-content"}, + }, + FluentBitFilters: []telemetryv1beta1.LogPipelineFilter{ + {Custom: "name stdout"}, + }, + Transforms: []telemetryv1beta1.TransformSpec{ + { + Conditions: []string{"resource.attributes[\"k8s.pod.name\"] == nil"}, + Statements: []string{"set(resource.attributes[\"k8s.pod.name\"]", "nginx"}, }, - Transforms: []telemetryv1beta1.TransformSpec{ - { - Conditions: []string{"resource.attributes[\"k8s.pod.name\"] == nil"}, - Statements: []string{"set(resource.attributes[\"k8s.pod.name\"]", "nginx"}, - }, + }, + Filters: []telemetryv1beta1.FilterSpec{ + { + Conditions: []string{"log.time == nil"}, }, - Filters: []telemetryv1beta1.FilterSpec{ - { - Conditions: []string{"log.time == nil"}, + }, + Output: telemetryv1beta1.LogPipelineOutput{ + Custom: "custom-output", + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ + Value: "http://localhost", }, - }, - Output: telemetryv1beta1.LogPipelineOutput{ - Custom: "custom-output", - HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ - Host: telemetryv1beta1.ValueType{ - Value: "http://localhost", + User: &telemetryv1beta1.ValueType{ + Value: "user", + }, + Password: &telemetryv1beta1.ValueType{ + ValueFrom: &telemetryv1beta1.ValueFromSource{ + SecretKeyRef: &telemetryv1beta1.SecretKeyRef{ + Name: "secret-name", + Namespace: "secret-namespace", + Key: "secret-key", + }, }, - User: &telemetryv1beta1.ValueType{ + }, + URI: "/ingest/v1beta1/logs", + Port: "8080", + Compress: "on", + Format: "json", + TLSConfig: telemetryv1beta1.OutputTLS{ + SkipCertificateValidation: true, + CA: &telemetryv1beta1.ValueType{ + Value: "ca", + }, + Cert: &telemetryv1beta1.ValueType{ + Value: "cert", + }, + Key: &telemetryv1beta1.ValueType{ + Value: "key", + }, + }, + Dedot: true, + }, + OTLP: &telemetryv1beta1.OTLPOutput{ + Protocol: telemetryv1beta1.OTLPProtocolGRPC, + Endpoint: telemetryv1beta1.ValueType{Value: "localhost:4317"}, + Path: "/v1/logs", + Authentication: &telemetryv1beta1.AuthenticationOptions{Basic: &telemetryv1beta1.BasicAuthOptions{ + User: telemetryv1beta1.ValueType{ Value: "user", }, - Password: &telemetryv1beta1.ValueType{ - ValueFrom: &telemetryv1beta1.ValueFromSource{ - SecretKeyRef: &telemetryv1beta1.SecretKeyRef{ - Name: "secret-name", - Namespace: "secret-namespace", - Key: "secret-key", + Password: telemetryv1beta1.ValueType{ + Value: "password", + }, + }}, + Headers: []telemetryv1beta1.Header{ + { + Name: "header1", + ValueType: telemetryv1beta1.ValueType{ + Value: "value1", + }, + Prefix: "prefix1", + }, + { + Name: "header2", + ValueType: telemetryv1beta1.ValueType{ + Value: "value2", + }, + Prefix: "prefix2", + }, + }, + TLS: &telemetryv1beta1.OutputTLS{ + Disabled: true, + SkipCertificateValidation: true, + CA: &telemetryv1beta1.ValueType{Value: "ca"}, + Cert: &telemetryv1beta1.ValueType{Value: "cert"}, + Key: &telemetryv1beta1.ValueType{Value: "key"}, + }, + }, + }, + }, + Status: telemetryv1beta1.LogPipelineStatus{ + Conditions: []metav1.Condition{ + { + Type: "LogAgentHealthy", + Status: "True", + Reason: "FluentBitReady", + Message: "FluentBit is and collecting logs", + }, + }, + UnsupportedMode: ptr.To(true), + }, +} + +func TestLogPipelineConvertTo(t *testing.T) { + tests := []struct { + name string + input *LogPipeline + expected *telemetryv1beta1.LogPipeline + }{ + { + name: "should sanitize otlp namespace selectors", + input: &LogPipeline{ + Spec: LogPipelineSpec{ + Input: LogPipelineInput{ + OTLP: &OTLPInput{ + Namespaces: &NamespaceSelector{ + Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, + Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, + }, + }, + }, + }, + }, + expected: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"valid-ns", "another-valid-ns"}, + Exclude: []string{"valid-excluded", "another-valid-excluded"}, }, }, }, - URI: "/ingest/v1beta1/logs", - Port: "8080", - Compress: "on", - Format: "json", - TLSConfig: telemetryv1beta1.OutputTLS{ - SkipCertificateValidation: true, - CA: &telemetryv1beta1.ValueType{ - Value: "ca", + }, + }, + }, + { + name: "should sanitize application namespace selectors", + input: &LogPipeline{ + Spec: LogPipelineSpec{ + Input: LogPipelineInput{ + Application: &LogPipelineApplicationInput{ + Namespaces: LogPipelineNamespaceSelector{ + Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, + Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, + }, }, - Cert: &telemetryv1beta1.ValueType{ - Value: "cert", + }, + }, + }, + expected: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"valid-ns", "another-valid-ns"}, + Exclude: []string{"valid-excluded", "another-valid-excluded"}, + }, }, - Key: &telemetryv1beta1.ValueType{ - Value: "key", + }, + }, + }, + }, + { + name: "should fill default exclude if nothing is defined", + input: &LogPipeline{ + Spec: LogPipelineSpec{ + Input: LogPipelineInput{ + Application: &LogPipelineApplicationInput{ + Namespaces: LogPipelineNamespaceSelector{}, }, }, - Dedot: true, }, - OTLP: &telemetryv1beta1.OTLPOutput{ - Protocol: telemetryv1beta1.OTLPProtocolGRPC, - Endpoint: telemetryv1beta1.ValueType{Value: "localhost:4317"}, - Path: "/v1/logs", - Authentication: &telemetryv1beta1.AuthenticationOptions{Basic: &telemetryv1beta1.BasicAuthOptions{ - User: telemetryv1beta1.ValueType{ - Value: "user", + }, + expected: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + }, }, - Password: telemetryv1beta1.ValueType{ - Value: "password", + }, + }, + }, + }, + { + name: "should not fill defaults if includes are defined", + input: &LogPipeline{ + Spec: LogPipelineSpec{ + Input: LogPipelineInput{ + Application: &LogPipelineApplicationInput{ + Namespaces: LogPipelineNamespaceSelector{ + Include: []string{"test"}, + }, }, - }}, - Headers: []telemetryv1beta1.Header{ - { - Name: "header1", - ValueType: telemetryv1beta1.ValueType{ - Value: "value1", + }, + }, + }, + expected: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"test"}, }, - Prefix: "prefix1", }, - { - Name: "header2", - ValueType: telemetryv1beta1.ValueType{ - Value: "value2", + }, + }, + }, + }, + { + name: "should not fill defaults if excludes are defined", + input: &LogPipeline{ + Spec: LogPipelineSpec{ + Input: LogPipelineInput{ + Application: &LogPipelineApplicationInput{ + Namespaces: LogPipelineNamespaceSelector{ + Exclude: []string{"test"}, }, - Prefix: "prefix2", }, }, - TLS: &telemetryv1beta1.OutputTLS{ - Disabled: true, - SkipCertificateValidation: true, - CA: &telemetryv1beta1.ValueType{Value: "ca"}, - Cert: &telemetryv1beta1.ValueType{Value: "cert"}, - Key: &telemetryv1beta1.ValueType{Value: "key"}, + }, + }, + expected: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"test"}, + }, + }, }, }, }, }, - Status: telemetryv1beta1.LogPipelineStatus{ - Conditions: []metav1.Condition{ - { - Type: "LogAgentHealthy", - Status: "True", - Reason: "FluentBitReady", - Message: "FluentBit is and collecting logs", + { + name: "should not fill defaults if system is true", + input: &LogPipeline{ + Spec: LogPipelineSpec{ + Input: LogPipelineInput{ + Application: &LogPipelineApplicationInput{ + Namespaces: LogPipelineNamespaceSelector{ + System: true, + }, + }, + }, + }, + }, + expected: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{}, + }, + }, }, }, - UnsupportedMode: ptr.To(true), + }, + { + name: "should convert all fields", + input: v1alpha1LogPipeline, + expected: v1beta1LogPipeline, }, } - dst := &LogPipeline{} - - err := dst.ConvertFrom(src) - require.NoError(t, err, "expected no error during ConvertTo") - - requireLogPipelinesEquivalent(t, dst, src) - - srcAfterRoundTrip := &telemetryv1beta1.LogPipeline{} - err = dst.ConvertTo(srcAfterRoundTrip) - require.NoError(t, err, "expected no error during ConvertFrom (round-trip)") - require.Empty(t, cmp.Diff(src, srcAfterRoundTrip), "expected source be equal to itself after round-trip") + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dst := &telemetryv1beta1.LogPipeline{} + err := tt.input.ConvertTo(dst) + require.NoError(t, err) + require.Equal(t, tt.expected, dst) + }) + } } -func requireLogPipelinesEquivalent(t *testing.T, x *LogPipeline, y *telemetryv1beta1.LogPipeline) { - require.Equal(t, x.ObjectMeta, y.ObjectMeta) - - xAppInput := x.Spec.Input.Application - yRuntimeInput := y.Spec.Input.Runtime - require.Equal(t, xAppInput.Namespaces.Include, yRuntimeInput.Namespaces.Include, "included namespaces mismatch") - require.Equal(t, xAppInput.Namespaces.Exclude, yRuntimeInput.Namespaces.Exclude, "excluded namespaces mismatch") - require.Equal(t, xAppInput.Namespaces.System, yRuntimeInput.Namespaces.System, "system namespaces mismatch") - require.Equal(t, xAppInput.Containers.Include, yRuntimeInput.Containers.Include, "included containers mismatch") - require.Equal(t, xAppInput.Containers.Exclude, yRuntimeInput.Containers.Exclude, "excluded containers mismatch") - require.Equal(t, xAppInput.KeepAnnotations, yRuntimeInput.KeepAnnotations, "keep annotations mismatch") - require.Equal(t, xAppInput.DropLabels, yRuntimeInput.DropLabels, "drop labels mismatch") - require.Equal(t, xAppInput.KeepOriginalBody, yRuntimeInput.KeepOriginalBody, "keep original body mismatch") - - xOTLPInput := x.Spec.Input.OTLP - yOTLPInput := y.Spec.Input.OTLP - require.Equal(t, xOTLPInput.Disabled, yOTLPInput.Disabled, "OTLP input disabled mismatch") - require.Equal(t, xOTLPInput.Namespaces.Include, yOTLPInput.Namespaces.Include, "OTLP included namespaces mismatch") - require.Equal(t, xOTLPInput.Namespaces.Exclude, yOTLPInput.Namespaces.Exclude, "OTLP excluded namespaces mismatch") - - require.Len(t, y.Spec.Files, 1, "expected one file") - require.Equal(t, x.Spec.Files[0].Name, y.Spec.Files[0].Name, "file name mismatch") - - require.Len(t, y.Spec.FluentBitFilters, 1, "expected one filter") - require.Equal(t, x.Spec.FluentBitFilters[0].Custom, y.Spec.FluentBitFilters[0].Custom, "custom filter mismatch") - - require.Equal(t, x.Spec.Output.Custom, y.Spec.Output.Custom, "custom output mismatch") - - xHTTP := x.Spec.Output.HTTP - yHTTP := y.Spec.Output.HTTP - require.Equal(t, xHTTP.Host.Value, yHTTP.Host.Value, "HTTP host mismatch") - require.Equal(t, xHTTP.User.Value, yHTTP.User.Value, "HTTP user mismatch") - require.Equal(t, xHTTP.Password.ValueFrom.SecretKeyRef.Name, yHTTP.Password.ValueFrom.SecretKeyRef.Name, "HTTP password secret name mismatch") - require.Equal(t, xHTTP.Password.ValueFrom.SecretKeyRef.Namespace, yHTTP.Password.ValueFrom.SecretKeyRef.Namespace, "HTTP password secret namespace mismatch") - require.Equal(t, xHTTP.Password.ValueFrom.SecretKeyRef.Key, yHTTP.Password.ValueFrom.SecretKeyRef.Key, "HTTP password secret key mismatch") - require.Equal(t, xHTTP.URI, yHTTP.URI, "HTTP URI mismatch") - require.Equal(t, xHTTP.Port, yHTTP.Port, "HTTP port mismatch") - require.Equal(t, xHTTP.Compress, yHTTP.Compress, "HTTP compress mismatch") - require.Equal(t, xHTTP.Format, yHTTP.Format, "HTTP format mismatch") - require.Equal(t, xHTTP.TLS.SkipCertificateValidation, yHTTP.TLSConfig.SkipCertificateValidation, "HTTP TLS skip certificate validation mismatch") - require.Equal(t, xHTTP.TLS.CA.Value, yHTTP.TLSConfig.CA.Value, "HTTP TLS CA mismatch") - require.Equal(t, xHTTP.TLS.Cert.Value, yHTTP.TLSConfig.Cert.Value, "HTTP TLS cert mismatch") - require.Equal(t, xHTTP.TLS.Key.Value, yHTTP.TLSConfig.Key.Value, "HTTP TLS key mismatch") - - xOTLP := x.Spec.Output.OTLP - yOTLP := y.Spec.Output.OTLP - - require.NotNil(t, xOTLP, "expected OTLP output") - require.NotNil(t, yOTLP, "expected OTLP output") - require.Equal(t, xOTLP.Protocol, string(yOTLP.Protocol), "OTLP protocol mismatch") - require.Equal(t, xOTLP.Endpoint.Value, yOTLP.Endpoint.Value, "OTLP endpoint mismatch") - require.Equal(t, xOTLP.Path, yOTLP.Path, "OTLP path mismatch") - require.Equal(t, xOTLP.Authentication.Basic.User.Value, yOTLP.Authentication.Basic.User.Value, "OTLP basic auth user mismatch") - require.Equal(t, xOTLP.Authentication.Basic.Password.Value, yOTLP.Authentication.Basic.Password.Value, "OTLP basic auth password mismatch") - require.Len(t, yOTLP.Headers, 2, "expected two headers") - require.Equal(t, xOTLP.Headers[0].Name, yOTLP.Headers[0].Name, "OTLP header name mismatch") - require.Equal(t, xOTLP.Headers[0].Value, yOTLP.Headers[0].Value, "OTLP header value mismatch") - require.Equal(t, xOTLP.Headers[0].Prefix, yOTLP.Headers[0].Prefix, "OTLP header prefix mismatch") - require.Equal(t, xOTLP.Headers[1].Name, yOTLP.Headers[1].Name, "OTLP header name mismatch") - require.Equal(t, xOTLP.Headers[1].Value, yOTLP.Headers[1].Value, "OTLP header value mismatch") - require.Equal(t, xOTLP.Headers[1].Prefix, yOTLP.Headers[1].Prefix, "OTLP header prefix mismatch") - require.Equal(t, xOTLP.TLS.Insecure, yOTLP.TLS.Disabled, "OTLP TLS insecure mismatch") - require.Equal(t, xOTLP.TLS.InsecureSkipVerify, yOTLP.TLS.SkipCertificateValidation, "OTLP TLS insecure skip verify mismatch") - require.Equal(t, xOTLP.TLS.CA.Value, yOTLP.TLS.CA.Value, "OTLP TLS CA mismatch") - require.Equal(t, xOTLP.TLS.Cert.Value, yOTLP.TLS.Cert.Value, "OTLP TLS cert mismatch") - require.Equal(t, xOTLP.TLS.Key.Value, yOTLP.TLS.Key.Value, "OTLP TLS key mismatch") - - require.Equal(t, x.Status.UnsupportedMode, y.Status.UnsupportedMode, "status unsupported mode mismatch") - require.ElementsMatch(t, x.Status.Conditions, y.Status.Conditions, "status conditions mismatch") - - xTransforms := x.Spec.Transforms - yTransforms := y.Spec.Transforms - require.Len(t, xTransforms, len(yTransforms), "expected same number of transforms") - - for i := range xTransforms { - require.ElementsMatch(t, xTransforms[i].Conditions, yTransforms[i].Conditions, "transform conditions mismatch at index %d", i) - require.Equal(t, xTransforms[i].Statements, yTransforms[i].Statements, "transform statements mismatch at index %d", i) +func TestLogPipelineConvertFrom(t *testing.T) { + tests := []struct { + name string + input *telemetryv1beta1.LogPipeline + expected *LogPipeline + }{ + { + name: "should convert namespace selectors without validation", + input: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"valid-ns", "Invalid_NS"}, + Exclude: []string{"valid-excluded", "Invalid@NS"}, + }, + }, + }, + }, + }, + expected: &LogPipeline{ + Spec: LogPipelineSpec{ + Input: LogPipelineInput{ + Application: &LogPipelineApplicationInput{ + Namespaces: LogPipelineNamespaceSelector{ + Include: []string{"valid-ns", "Invalid_NS"}, + Exclude: []string{"valid-excluded", "Invalid@NS"}, + }, + }, + }, + }, + }, + }, + { + name: "should convert all fields", + input: v1beta1LogPipeline, + expected: v1alpha1LogPipeline, + }, } - xFilter := x.Spec.Filters - yFilter := y.Spec.Filters - - require.Len(t, xFilter, len(yFilter), "expected same number of filters") - - for i := range xFilter { - require.ElementsMatch(t, xFilter[i].Conditions, yFilter[i].Conditions, "filter conditions mismatch at index %d", i) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dst := &LogPipeline{} + err := dst.ConvertFrom(tt.input) + require.NoError(t, err) + require.Equal(t, tt.expected, dst) + }) } } diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion.go b/apis/telemetry/v1alpha1/metricpipeline_conversion.go index dfbc6c27c6..d79ebda3ca 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion.go @@ -1,16 +1,22 @@ package v1alpha1 import ( - "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" - telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + "errors" + + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/conversion" + + telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" ) +var errSrcTypeUnsupportedMetricPipeline = errors.New("source type is not MetricPipeline v1alpha1") +var errDstTypeUnsupportedMetricPipeline = errors.New("destination type is not MetricPipeline v1beta1") + // ConvertTo implements conversion.Hub for MetricPipeline (v1alpha1 -> v1beta1) func (src *MetricPipeline) ConvertTo(dstRaw conversion.Hub) error { dst, ok := dstRaw.(*telemetryv1beta1.MetricPipeline) if !ok { - return errDstTypeUnsupported + return errDstTypeUnsupportedMetricPipeline } // Copy metadata @@ -25,6 +31,7 @@ func (src *MetricPipeline) ConvertTo(dstRaw conversion.Hub) error { DiagnosticMetrics: convertDiagnosticMetricsToBeta(src.Spec.Input.Prometheus.DiagnosticMetrics), } } + if src.Spec.Input.Runtime != nil { dst.Spec.Input.Runtime = &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: src.Spec.Input.Runtime.Enabled, @@ -32,6 +39,7 @@ func (src *MetricPipeline) ConvertTo(dstRaw conversion.Hub) error { Resources: convertRuntimeResourcesToBeta(src.Spec.Input.Runtime.Resources), } } + if src.Spec.Input.Istio != nil { dst.Spec.Input.Istio = &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: src.Spec.Input.Istio.Enabled, @@ -40,31 +48,41 @@ func (src *MetricPipeline) ConvertTo(dstRaw conversion.Hub) error { EnvoyMetrics: convertEnvoyMetricsToBeta(src.Spec.Input.Istio.EnvoyMetrics), } } + if src.Spec.Input.OTLP != nil { dst.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{ - Disabled: src.Spec.Input.OTLP.Disabled, + Enabled: ptr.To(!src.Spec.Input.OTLP.Disabled), Namespaces: convertNamespaceSelectorToBeta(src.Spec.Input.OTLP.Namespaces), } } + dst.Spec.Output = telemetryv1beta1.MetricPipelineOutput{} if src.Spec.Output.OTLP != nil { dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) } - for _, t := range src.Spec.Transforms { - dst.Spec.Transforms = append(dst.Spec.Transforms, telemetryv1beta1.TransformSpec(t)) + + if src.Spec.Transforms != nil { + for _, t := range src.Spec.Transforms { + dst.Spec.Transforms = append(dst.Spec.Transforms, convertTransformSpecToBeta(t)) + } } - for _, f := range src.Spec.Filters { - dst.Spec.Filter = append(dst.Spec.Filter, telemetryv1beta1.FilterSpec(f)) + + if src.Spec.Filters != nil { + for _, t := range src.Spec.Filters { + dst.Spec.Filters = append(dst.Spec.Filters, convertFilterSpecToBeta(t)) + } } + dst.Status = telemetryv1beta1.MetricPipelineStatus(src.Status) + return nil } // ConvertFrom implements conversion.Hub for MetricPipeline (v1beta1 -> v1alpha1) func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { - src, ok := srcRaw.(*v1beta1.MetricPipeline) + src, ok := srcRaw.(*telemetryv1beta1.MetricPipeline) if !ok { - return nil + return errSrcTypeUnsupportedMetricPipeline } // Copy metadata @@ -79,6 +97,7 @@ func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { DiagnosticMetrics: convertDiagnosticMetricsToAlpha(src.Spec.Input.Prometheus.DiagnosticMetrics), } } + if src.Spec.Input.Runtime != nil { dst.Spec.Input.Runtime = &MetricPipelineRuntimeInput{ Enabled: src.Spec.Input.Runtime.Enabled, @@ -86,6 +105,7 @@ func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { Resources: convertRuntimeResourcesToAlpha(src.Spec.Input.Runtime.Resources), } } + if src.Spec.Input.Istio != nil { dst.Spec.Input.Istio = &MetricPipelineIstioInput{ Enabled: src.Spec.Input.Istio.Enabled, @@ -94,41 +114,42 @@ func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { EnvoyMetrics: convertEnvoyMetricsToAlpha(src.Spec.Input.Istio.EnvoyMetrics), } } + if src.Spec.Input.OTLP != nil { dst.Spec.Input.OTLP = &OTLPInput{ - Disabled: src.Spec.Input.OTLP.Disabled, + Disabled: src.Spec.Input.OTLP.Enabled != nil && !*src.Spec.Input.OTLP.Enabled, Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.OTLP.Namespaces), } } + dst.Spec.Output = MetricPipelineOutput{} if src.Spec.Output.OTLP != nil { dst.Spec.Output.OTLP = convertOTLPOutputToAlpha(src.Spec.Output.OTLP) } - for _, t := range src.Spec.Transforms { - dst.Spec.Transforms = append(dst.Spec.Transforms, TransformSpec(t)) + + if src.Spec.Transforms != nil { + for _, t := range src.Spec.Transforms { + dst.Spec.Transforms = append(dst.Spec.Transforms, convertTransformSpecToAlpha(t)) + } } - for _, f := range src.Spec.Filter { - dst.Spec.Filters = append(dst.Spec.Filters, FilterSpec(f)) + + if src.Spec.Filters != nil { + for _, t := range src.Spec.Filters { + dst.Spec.Filters = append(dst.Spec.Filters, convertFilterSpecToAlpha(t)) + } } + dst.Status = MetricPipelineStatus(src.Status) + return nil } // Helper conversion functions -func convertNamespaceSelectorToAlpha(ns *telemetryv1beta1.NamespaceSelector) *NamespaceSelector { - if ns == nil { - return nil - } - return &NamespaceSelector{ - Include: append([]string{}, ns.Include...), - Exclude: append([]string{}, ns.Exclude...), - } -} - func convertDiagnosticMetricsToBeta(dm *MetricPipelineIstioInputDiagnosticMetrics) *telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics { if dm == nil { return nil } + return &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ Enabled: dm.Enabled, } @@ -138,6 +159,7 @@ func convertDiagnosticMetricsToAlpha(dm *telemetryv1beta1.MetricPipelineIstioInp if dm == nil { return nil } + return &MetricPipelineIstioInputDiagnosticMetrics{ Enabled: dm.Enabled, } @@ -147,6 +169,7 @@ func convertEnvoyMetricsToBeta(em *EnvoyMetrics) *telemetryv1beta1.EnvoyMetrics if em == nil { return nil } + return &telemetryv1beta1.EnvoyMetrics{ Enabled: em.Enabled, } @@ -156,6 +179,7 @@ func convertEnvoyMetricsToAlpha(em *telemetryv1beta1.EnvoyMetrics) *EnvoyMetrics if em == nil { return nil } + return &EnvoyMetrics{ Enabled: em.Enabled, } @@ -165,6 +189,7 @@ func convertRuntimeResourcesToBeta(r *MetricPipelineRuntimeInputResources) *tele if r == nil { return nil } + return &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Pod: convertRuntimeResourceToBeta(r.Pod), Container: convertRuntimeResourceToBeta(r.Container), @@ -181,6 +206,7 @@ func convertRuntimeResourcesToAlpha(r *telemetryv1beta1.MetricPipelineRuntimeInp if r == nil { return nil } + return &MetricPipelineRuntimeInputResources{ Pod: convertRuntimeResourceToAlpha(r.Pod), Container: convertRuntimeResourceToAlpha(r.Container), @@ -197,6 +223,7 @@ func convertRuntimeResourceToBeta(r *MetricPipelineRuntimeInputResource) *teleme if r == nil { return nil } + return &telemetryv1beta1.MetricPipelineRuntimeInputResource{ Enabled: r.Enabled, } @@ -206,193 +233,8 @@ func convertRuntimeResourceToAlpha(r *telemetryv1beta1.MetricPipelineRuntimeInpu if r == nil { return nil } + return &MetricPipelineRuntimeInputResource{ Enabled: r.Enabled, } } - -func convertOTLPOutputToBeta(o *OTLPOutput) *telemetryv1beta1.OTLPOutput { - if o == nil { - return nil - } - return &telemetryv1beta1.OTLPOutput{ - Protocol: telemetryv1beta1.OTLPProtocol(o.Protocol), - Endpoint: convertValueTypeToBeta(o.Endpoint), - Path: o.Path, - Authentication: convertAuthenticationToBeta(o.Authentication), - Headers: convertHeadersToBeta(o.Headers), - TLS: convertOTLPTLSToBeta(o.TLS), - } -} - -func convertOTLPOutputToAlpha(o *telemetryv1beta1.OTLPOutput) *OTLPOutput { - if o == nil { - return nil - } - return &OTLPOutput{ - Protocol: string(o.Protocol), - Endpoint: convertValueTypeToAlpha(o.Endpoint), - Path: o.Path, - Authentication: convertAuthenticationToAlpha(o.Authentication), - Headers: convertHeadersToAlpha(o.Headers), - TLS: convertOTLPTLSToAlpha(o.TLS), - } -} - -func convertValueTypeToBeta(v ValueType) telemetryv1beta1.ValueType { - return telemetryv1beta1.ValueType{ - Value: v.Value, - ValueFrom: convertValueFromSourceToBeta(v.ValueFrom), - } -} - -func convertValueTypeToAlpha(v telemetryv1beta1.ValueType) ValueType { - return ValueType{ - Value: v.Value, - ValueFrom: convertValueFromSourceToAlpha(v.ValueFrom), - } -} - -func convertValueFromSourceToBeta(v *ValueFromSource) *telemetryv1beta1.ValueFromSource { - if v == nil { - return nil - } - return &telemetryv1beta1.ValueFromSource{ - SecretKeyRef: convertSecretKeyRefToBeta(v.SecretKeyRef), - } -} - -func convertValueFromSourceToAlpha(v *telemetryv1beta1.ValueFromSource) *ValueFromSource { - if v == nil { - return nil - } - return &ValueFromSource{ - SecretKeyRef: convertSecretKeyRefToAlpha(v.SecretKeyRef), - } -} - -func convertSecretKeyRefToBeta(s *SecretKeyRef) *telemetryv1beta1.SecretKeyRef { - if s == nil { - return nil - } - return &telemetryv1beta1.SecretKeyRef{ - Name: s.Name, - Namespace: s.Namespace, - Key: s.Key, - } -} - -func convertSecretKeyRefToAlpha(s *telemetryv1beta1.SecretKeyRef) *SecretKeyRef { - if s == nil { - return nil - } - return &SecretKeyRef{ - Name: s.Name, - Namespace: s.Namespace, - Key: s.Key, - } -} - -func convertAuthenticationToBeta(a *AuthenticationOptions) *telemetryv1beta1.AuthenticationOptions { - if a == nil { - return nil - } - return &telemetryv1beta1.AuthenticationOptions{ - Basic: convertBasicAuthToBeta(a.Basic), - } -} - -func convertAuthenticationToAlpha(a *telemetryv1beta1.AuthenticationOptions) *AuthenticationOptions { - if a == nil { - return nil - } - return &AuthenticationOptions{ - Basic: convertBasicAuthToAlpha(a.Basic), - } -} - -func convertBasicAuthToBeta(b *BasicAuthOptions) *telemetryv1beta1.BasicAuthOptions { - if b == nil { - return nil - } - return &telemetryv1beta1.BasicAuthOptions{ - User: convertValueTypeToBeta(b.User), - Password: convertValueTypeToBeta(b.Password), - } -} - -func convertBasicAuthToAlpha(b *telemetryv1beta1.BasicAuthOptions) *BasicAuthOptions { - if b == nil { - return nil - } - return &BasicAuthOptions{ - User: convertValueTypeToAlpha(b.User), - Password: convertValueTypeToAlpha(b.Password), - } -} - -func convertHeadersToBeta(hs []Header) []telemetryv1beta1.Header { - var out []telemetryv1beta1.Header - for _, h := range hs { - out = append(out, telemetryv1beta1.Header{ - ValueType: convertValueTypeToBeta(h.ValueType), - Name: h.Name, - Prefix: h.Prefix, - }) - } - return out -} - -func convertHeadersToAlpha(hs []telemetryv1beta1.Header) []Header { - var out []Header - for _, h := range hs { - out = append(out, Header{ - ValueType: convertValueTypeToAlpha(h.ValueType), - Name: h.Name, - Prefix: h.Prefix, - }) - } - return out -} - -func convertOTLPTLSToBeta(t *OTLPTLS) *telemetryv1beta1.OutputTLS { - if t == nil { - return nil - } - return &telemetryv1beta1.OutputTLS{ - Disabled: t.Insecure, - SkipCertificateValidation: t.InsecureSkipVerify, - CA: convertValueTypeToBetaPtr(t.CA), - Cert: convertValueTypeToBetaPtr(t.Cert), - Key: convertValueTypeToBetaPtr(t.Key), - } -} - -func convertOTLPTLSToAlpha(t *telemetryv1beta1.OutputTLS) *OTLPTLS { - if t == nil { - return nil - } - return &OTLPTLS{ - Insecure: t.Disabled, - InsecureSkipVerify: t.SkipCertificateValidation, - CA: convertValueTypeToAlphaPtr(t.CA), - Cert: convertValueTypeToAlphaPtr(t.Cert), - Key: convertValueTypeToAlphaPtr(t.Key), - } -} - -func convertValueTypeToBetaPtr(v *ValueType) *telemetryv1beta1.ValueType { - if v == nil { - return nil - } - vt := convertValueTypeToBeta(*v) - return &vt -} - -func convertValueTypeToAlphaPtr(v *telemetryv1beta1.ValueType) *ValueType { - if v == nil { - return nil - } - vt := convertValueTypeToAlpha(*v) - return &vt -} diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go b/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go index 90b87a94a2..ad26a505a6 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go @@ -3,14 +3,213 @@ package v1alpha1 import ( "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" + + telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" ) -func boolPtr(b bool) *bool { - return &b +var v1alpha1MetricPipeline = &MetricPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "full-pipeline", + Namespace: "default", + }, + Spec: MetricPipelineSpec{ + Input: MetricPipelineInput{ + Runtime: &MetricPipelineRuntimeInput{ + Enabled: ptr.To(true), + Namespaces: &NamespaceSelector{ + Include: []string{"ns-1", "ns-2"}, + Exclude: []string{"ns-3"}, + }, + Resources: &MetricPipelineRuntimeInputResources{ + Pod: &MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Container: &MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Node: &MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Volume: &MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Deployment: &MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + DaemonSet: &MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + StatefulSet: &MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Job: &MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + }, + }, + Istio: &MetricPipelineIstioInput{ + Enabled: ptr.To(false), + Namespaces: &NamespaceSelector{ + Include: []string{"app-ns-1"}, + Exclude: []string{"app-ns-2"}, + }, + DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: ptr.To(true), + }, + EnvoyMetrics: &EnvoyMetrics{ + Enabled: ptr.To(true), + }, + }, + Prometheus: &MetricPipelinePrometheusInput{ + Enabled: ptr.To(true), + Namespaces: &NamespaceSelector{ + Include: []string{"prom-ns-1"}, + Exclude: []string{"prom-ns-2"}, + }, + DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: ptr.To(true), + }, + }, + OTLP: &OTLPInput{ + Disabled: true, + Namespaces: &NamespaceSelector{ + Include: []string{"otlp-ns-1"}, + Exclude: []string{"otlp-ns-2"}, + }, + }, + }, + Output: MetricPipelineOutput{ + OTLP: &OTLPOutput{ + Endpoint: ValueType{ + Value: "otlp-collector:4317", + }, + TLS: &OTLPTLS{ + Insecure: false, + InsecureSkipVerify: true, + CA: &ValueType{Value: "ca-cert"}, + Cert: &ValueType{Value: "cert"}, + Key: &ValueType{Value: "key"}, + }, + Headers: []Header{ + {Name: "header1", ValueType: ValueType{Value: "value1"}, Prefix: "myPrefix"}, + }, + }, + }, + }, + Status: MetricPipelineStatus{ + Conditions: []metav1.Condition{ + { + Type: "type", + Status: "True", + Reason: "Ready", + Message: "message", + }, + }, + }, +} + +var v1beta1MetricPipeline = &telemetryv1beta1.MetricPipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "full-pipeline", + Namespace: "default", + }, + Spec: telemetryv1beta1.MetricPipelineSpec{ + Input: telemetryv1beta1.MetricPipelineInput{ + Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ + Enabled: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"ns-1", "ns-2"}, + Exclude: []string{"ns-3"}, + }, + Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ + Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Container: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Node: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Volume: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Deployment: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + DaemonSet: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + StatefulSet: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + Job: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ + Enabled: ptr.To(false), + }, + }, + }, + Istio: &telemetryv1beta1.MetricPipelineIstioInput{ + Enabled: ptr.To(false), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"app-ns-1"}, + Exclude: []string{"app-ns-2"}, + }, + DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: ptr.To(true), + }, + EnvoyMetrics: &telemetryv1beta1.EnvoyMetrics{ + Enabled: ptr.To(true), + }, + }, + Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ + Enabled: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"prom-ns-1"}, + Exclude: []string{"prom-ns-2"}, + }, + DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: ptr.To(true), + }, + }, + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Include: []string{"otlp-ns-1"}, + Exclude: []string{"otlp-ns-2"}, + }, + }, + }, + Output: telemetryv1beta1.MetricPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "otlp-collector:4317", + }, + TLS: &telemetryv1beta1.OutputTLS{ + Disabled: false, + SkipCertificateValidation: true, + CA: &telemetryv1beta1.ValueType{Value: "ca-cert"}, + Cert: &telemetryv1beta1.ValueType{Value: "cert"}, + Key: &telemetryv1beta1.ValueType{Value: "key"}, + }, + Headers: []telemetryv1beta1.Header{ + {Name: "header1", ValueType: telemetryv1beta1.ValueType{Value: "value1"}, Prefix: "myPrefix"}, + }, + }, + }, + }, + Status: telemetryv1beta1.MetricPipelineStatus{ + Conditions: []metav1.Condition{ + { + Type: "type", + Status: "True", + Reason: "Ready", + Message: "message", + }, + }, + }, } func TestMetricPipelineConvertTo(t *testing.T) { @@ -19,23 +218,6 @@ func TestMetricPipelineConvertTo(t *testing.T) { input *MetricPipeline expected *telemetryv1beta1.MetricPipeline }{ - { - name: "should convert basic fields", - input: &MetricPipeline{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pipeline", - Namespace: "test-ns", - }, - Spec: MetricPipelineSpec{}, - }, - expected: &telemetryv1beta1.MetricPipeline{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pipeline", - Namespace: "test-ns", - }, - Spec: telemetryv1beta1.MetricPipelineSpec{}, - }, - }, { name: "should sanitize namespace selectors", input: &MetricPipeline{ @@ -63,6 +245,11 @@ func TestMetricPipelineConvertTo(t *testing.T) { }, }, }, + { + name: "should convert all fields", + input: v1alpha1MetricPipeline, + expected: v1beta1MetricPipeline, + }, } for _, tt := range tests { @@ -70,7 +257,7 @@ func TestMetricPipelineConvertTo(t *testing.T) { dst := &telemetryv1beta1.MetricPipeline{} err := tt.input.ConvertTo(dst) require.NoError(t, err) - assert.Equal(t, tt.expected, dst) + require.Equal(t, tt.expected, dst) }) } } @@ -81,23 +268,6 @@ func TestMetricPipelineConvertFrom(t *testing.T) { input *telemetryv1beta1.MetricPipeline expected *MetricPipeline }{ - { - name: "should convert basic fields", - input: &telemetryv1beta1.MetricPipeline{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pipeline", - Namespace: "test-ns", - }, - Spec: telemetryv1beta1.MetricPipelineSpec{}, - }, - expected: &MetricPipeline{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pipeline", - Namespace: "test-ns", - }, - Spec: MetricPipelineSpec{}, - }, - }, { name: "should convert namespace selectors without validation", input: &telemetryv1beta1.MetricPipeline{ @@ -125,6 +295,11 @@ func TestMetricPipelineConvertFrom(t *testing.T) { }, }, }, + { + name: "should convert all fields", + input: v1beta1MetricPipeline, + expected: v1alpha1MetricPipeline, + }, } for _, tt := range tests { @@ -132,1124 +307,7 @@ func TestMetricPipelineConvertFrom(t *testing.T) { dst := &MetricPipeline{} err := dst.ConvertFrom(tt.input) require.NoError(t, err) - assert.Equal(t, tt.expected, dst) + require.Equal(t, tt.expected, dst) }) } } - -func TestMetricPipelineConvertTo_InvalidDestination(t *testing.T) { - src := &MetricPipeline{} - dst := &MetricPipeline{} // Wrong type for destination - err := src.ConvertTo(dst) - assert.Error(t, err) - assert.Contains(t, err.Error(), "dst object must be of type *v1beta1.MetricPipeline") -} - -func TestMetricPipelineConvertFrom_InvalidSource(t *testing.T) { - src := &MetricPipeline{} // Wrong type for source - dst := &MetricPipeline{} - err := dst.ConvertFrom(src) - assert.Error(t, err) - assert.Contains(t, err.Error(), "src object must be of type *v1beta1.MetricPipeline") -} - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func boolPtr(b bool) *bool { - - return &b - -} telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" - - - -func TestMetricPipelineConvertTo(t *testing.T) { metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - tests := []struct { - - name string)) - - input *MetricPipeline - - expected *telemetryv1beta1.MetricPipeline - - }{ - - {func boolPtr(b bool) *bool {func boolPtr(b bool) *bool { - - name: "should convert basic fields", - - input: &MetricPipeline{ return &b return &b - - ObjectMeta: metav1.ObjectMeta{ - - Name: "test-pipeline",}} - - Namespace: "test-ns", - - }, - - Spec: MetricPipelineSpec{}, - - },func TestMetricPipelineConvertTo(t *testing.T) {func TestMetricPipelineConvertTo(t *testing.T) { - - expected: &telemetryv1beta1.MetricPipeline{ - - ObjectMeta: metav1.ObjectMeta{ tests := []struct { tests := []struct { - - Name: "test-pipeline", - - Namespace: "test-ns", name string name string - - }, - - Spec: telemetryv1beta1.MetricPipelineSpec{}, input *MetricPipeline input *MetricPipeline - - }, - - }, expected *telemetryv1beta1.MetricPipeline expected *telemetryv1beta1.MetricPipeline - - { - - name: "should sanitize namespaces in namespace selectors", }{ }{ - - input: &MetricPipeline{ - - ObjectMeta: metav1.ObjectMeta{ { { - - Name: "test-pipeline", - - }, name: "should convert basic fields", name: "should convert basic fields", - - Spec: MetricPipelineSpec{ - - Input: MetricPipelineInput{ input: &MetricPipeline{ input: &MetricPipeline{ - - Runtime: &MetricPipelineRuntimeInput{ - - Namespaces: &NamespaceSelector{ ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ - - Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, - - Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, Name: "test-pipeline", Name: "test-pipeline", - - }, - - }, Namespace: "test-ns", Namespace: "test-ns", - - }, - - }, }, }, - - }, - - expected: &telemetryv1beta1.MetricPipeline{ Spec: MetricPipelineSpec{}, Spec: MetricPipelineSpec{}, - - ObjectMeta: metav1.ObjectMeta{ - - Name: "test-pipeline", }, }, - - }, - - Spec: telemetryv1beta1.MetricPipelineSpec{ expected: &telemetryv1beta1.MetricPipeline{ expected: &telemetryv1beta1.MetricPipeline{ - - Input: telemetryv1beta1.MetricPipelineInput{ - - Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ - - Namespaces: &telemetryv1beta1.NamespaceSelector{ - - Include: []string{"valid-ns", "another-valid-ns"}, Name: "test-pipeline", Name: "test-pipeline", - - Exclude: []string{"valid-excluded", "another-valid-excluded"}, - - }, Namespace: "test-ns", Namespace: "test-ns", - - }, - - }, }, }, - - }, - - }, Spec: telemetryv1beta1.MetricPipelineSpec{}, Spec: telemetryv1beta1.MetricPipelineSpec{}, - - }, - - { }, }, - - name: "should convert all input sections", - - input: &MetricPipeline{ }, }, - - Spec: MetricPipelineSpec{ - - Input: MetricPipelineInput{ { { - - Prometheus: &MetricPipelinePrometheusInput{ - - Enabled: boolPtr(true), name: "should sanitize namespaces in namespace selectors", name: "should sanitize namespaces in namespace selectors", - - Namespaces: &NamespaceSelector{ - - Include: []string{"ns1"}, input: &MetricPipeline{ input: &MetricPipeline{ - - }, - - }, ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ - - Runtime: &MetricPipelineRuntimeInput{ - - Enabled: boolPtr(true), Name: "test-pipeline", Name: "test-pipeline", - - Resources: &MetricPipelineRuntimeInputResources{ - - Pod: &MetricPipelineRuntimeInputResource{ }, }, - - Enabled: boolPtr(true), - - }, Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ - - }, - - }, Input: MetricPipelineInput{ Input: MetricPipelineInput{ - - Istio: &MetricPipelineIstioInput{ - - Enabled: boolPtr(true), Runtime: &MetricPipelineRuntimeInput{ Runtime: &MetricPipelineRuntimeInput{ - - DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ - - Enabled: boolPtr(true), Namespaces: &NamespaceSelector{ Namespaces: &NamespaceSelector{ - - }, - - }, Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, Include: []string{"valid-ns", "Invalid_NS", "another-valid-ns"}, - - OTLP: &OTLPInput{ - - Disabled: boolPtr(true), Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, Exclude: []string{"valid-excluded", "Invalid@NS", "another-valid-excluded"}, - - }, - - }, }, }, - - }, - - }, }, }, - - expected: &telemetryv1beta1.MetricPipeline{ - - Spec: telemetryv1beta1.MetricPipelineSpec{ }, }, - - Input: telemetryv1beta1.MetricPipelineInput{ - - Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ }, }, - - Enabled: boolPtr(true), - - Namespaces: &telemetryv1beta1.NamespaceSelector{ }, }, - - Include: []string{"ns1"}, - - }, expected: &telemetryv1beta1.MetricPipeline{ expected: &telemetryv1beta1.MetricPipeline{ - - }, - - Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ - - Enabled: boolPtr(true), - - Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Name: "test-pipeline", Name: "test-pipeline", - - Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ - - Enabled: boolPtr(true), }, }, - - }, - - }, Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ - - }, - - Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Input: telemetryv1beta1.MetricPipelineInput{ Input: telemetryv1beta1.MetricPipelineInput{ - - Enabled: boolPtr(true), - - DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ - - Enabled: boolPtr(true), - - }, Namespaces: &telemetryv1beta1.NamespaceSelector{ Namespaces: &telemetryv1beta1.NamespaceSelector{ - - }, - - OTLP: &telemetryv1beta1.OTLPInput{ Include: []string{"valid-ns", "another-valid-ns"}, Include: []string{"valid-ns", "another-valid-ns"}, - - Disabled: boolPtr(true), - - }, Exclude: []string{"valid-excluded", "another-valid-excluded"}, Exclude: []string{"valid-excluded", "another-valid-excluded"}, - - }, - - }, }, }, - - }, - - }, }, }, - - { - - name: "should convert output section with authentication", }, }, - - input: &MetricPipeline{ - - Spec: MetricPipelineSpec{ }, }, - - Output: MetricPipelineOutput{ - - OTLP: &OTLPOutput{ }, }, - - Protocol: "grpc", - - Endpoint: ValueType{ }, }, - - Value: "localhost:4317", - - }, { { - - Authentication: &AuthenticationOptions{ - - Basic: &BasicAuthOptions{ name: "should convert all input sections", name: "should convert all input sections", - - User: ValueType{ - - Value: "user", input: &MetricPipeline{ input: &MetricPipeline{ - - }, - - Password: ValueType{ Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ - - Value: "pass", - - }, Input: MetricPipelineInput{ Input: MetricPipelineInput{ - - }, - - }, Prometheus: &MetricPipelinePrometheusInput{ Prometheus: &MetricPipelinePrometheusInput{ - - }, - - }, Enabled: boolPtr(true), Enabled: true, - - }, - - }, Namespaces: &NamespaceSelector{ Namespaces: &NamespaceSelector{ - - expected: &telemetryv1beta1.MetricPipeline{ - - Spec: telemetryv1beta1.MetricPipelineSpec{ Include: []string{"ns1"}, Include: []string{"ns1"}, - - Output: telemetryv1beta1.MetricPipelineOutput{ - - OTLP: &telemetryv1beta1.OTLPOutput{ }, }, - - Protocol: "grpc", - - Endpoint: telemetryv1beta1.ValueType{ }, }, - - Value: "localhost:4317", - - }, Runtime: &MetricPipelineRuntimeInput{ Runtime: &MetricPipelineRuntimeInput{ - - Authentication: &telemetryv1beta1.AuthenticationOptions{ - - Basic: &telemetryv1beta1.BasicAuthOptions{ Enabled: boolPtr(true), Enabled: true, - - User: telemetryv1beta1.ValueType{ - - Value: "user", Resources: &MetricPipelineRuntimeInputResources{ Resources: &MetricPipelineRuntimeInputResources{ - - }, - - Password: telemetryv1beta1.ValueType{ Pod: &MetricPipelineRuntimeInputResource{ Pod: &MetricPipelineRuntimeInputResource{ - - Value: "pass", - - }, Enabled: boolPtr(true), Enabled: true, - - }, - - }, }, }, - - }, - - }, }, }, - - }, - - }, }, }, - - }, - - } Istio: &MetricPipelineIstioInput{ Istio: &MetricPipelineIstioInput{ - - - - for _, tt := range tests { Enabled: boolPtr(true), Enabled: true, - - t.Run(tt.name, func(t *testing.T) { - - dst := &telemetryv1beta1.MetricPipeline{} DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ - - err := tt.input.ConvertTo(dst) - - assert.NoError(t, err) Enabled: boolPtr(true), Enabled: true, - - assert.Equal(t, tt.expected, dst) - - }) }, }, - - } - -} }, }, - - - -func TestMetricPipelineConvertFrom(t *testing.T) { OTLP: &OTLPInput{ OTLP: &OTLPInput{ - - tests := []struct { - - name string Disabled: boolPtr(true), Disabled: true, - - input *telemetryv1beta1.MetricPipeline - - expected *MetricPipeline }, }, - - }{ - - { }, }, - - name: "should convert basic fields", - - input: &telemetryv1beta1.MetricPipeline{ }, }, - - ObjectMeta: metav1.ObjectMeta{ - - Name: "test-pipeline", }, }, - - Namespace: "test-ns", - - }, expected: &telemetryv1beta1.MetricPipeline{ expected: &telemetryv1beta1.MetricPipeline{ - - Spec: telemetryv1beta1.MetricPipelineSpec{}, - - }, Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ - - expected: &MetricPipeline{ - - ObjectMeta: metav1.ObjectMeta{ Input: telemetryv1beta1.MetricPipelineInput{ Input: telemetryv1beta1.MetricPipelineInput{ - - Name: "test-pipeline", - - Namespace: "test-ns", Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ - - }, - - Spec: MetricPipelineSpec{}, Enabled: boolPtr(true), Enabled: true, - - }, - - }, Namespaces: &telemetryv1beta1.NamespaceSelector{ Namespaces: &telemetryv1beta1.NamespaceSelector{ - - { - - name: "should convert namespaces in namespace selectors without validation", Include: []string{"ns1"}, Include: []string{"ns1"}, - - input: &telemetryv1beta1.MetricPipeline{ - - Spec: telemetryv1beta1.MetricPipelineSpec{ }, }, - - Input: telemetryv1beta1.MetricPipelineInput{ - - Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ }, }, - - Namespaces: &telemetryv1beta1.NamespaceSelector{ - - Include: []string{"valid-ns", "Invalid_NS"}, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ - - Exclude: []string{"valid-excluded", "Invalid@NS"}, - - }, Enabled: boolPtr(true), Enabled: true, - - }, - - }, Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ - - }, - - }, Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ - - expected: &MetricPipeline{ - - Spec: MetricPipelineSpec{ Enabled: boolPtr(true), Enabled: true, - - Input: MetricPipelineInput{ - - Runtime: &MetricPipelineRuntimeInput{ }, }, - - Namespaces: &NamespaceSelector{ - - Include: []string{"valid-ns", "Invalid_NS"}, }, }, - - Exclude: []string{"valid-excluded", "Invalid@NS"}, - - }, }, }, - - }, - - }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Istio: &telemetryv1beta1.MetricPipelineIstioInput{ - - }, - - }, Enabled: boolPtr(true), Enabled: true, - - }, - - { DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ - - name: "should convert all input sections", - - input: &telemetryv1beta1.MetricPipeline{ Enabled: boolPtr(true), Enabled: true, - - Spec: telemetryv1beta1.MetricPipelineSpec{ - - Input: telemetryv1beta1.MetricPipelineInput{ }, }, - - Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ - - Enabled: boolPtr(true), }, }, - - Namespaces: &telemetryv1beta1.NamespaceSelector{ - - Include: []string{"ns1"}, OTLP: &telemetryv1beta1.OTLPInput{ OTLP: &telemetryv1beta1.OTLPInput{ - - }, - - }, Disabled: boolPtr(true), Disabled: true, - - Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ - - Enabled: boolPtr(true), }, }, - - Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ - - Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ }, }, - - Enabled: boolPtr(true), - - }, }, }, - - }, - - }, }, }, - - Istio: &telemetryv1beta1.MetricPipelineIstioInput{ - - Enabled: boolPtr(true), }, }, - - DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ - - Enabled: boolPtr(true), { { - - }, - - }, name: "should convert output section with authentication", name: "should convert output section with authentication", - - OTLP: &telemetryv1beta1.OTLPInput{ - - Disabled: boolPtr(true), input: &MetricPipeline{ input: &MetricPipeline{ - - }, - - }, Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ - - }, - - }, Output: MetricPipelineOutput{ Output: MetricPipelineOutput{ - - expected: &MetricPipeline{ - - Spec: MetricPipelineSpec{ OTLP: &OTLPOutput{ OTLP: &OTLPOutput{ - - Input: MetricPipelineInput{ - - Prometheus: &MetricPipelinePrometheusInput{ Protocol: "grpc", Protocol: "grpc", - - Enabled: boolPtr(true), - - Namespaces: &NamespaceSelector{ Endpoint: ValueType{ Endpoint: ValueType{ - - Include: []string{"ns1"}, - - }, Value: "localhost:4317", Value: "localhost:4317", - - }, - - Runtime: &MetricPipelineRuntimeInput{ }, }, - - Enabled: boolPtr(true), - - Resources: &MetricPipelineRuntimeInputResources{ Authentication: &AuthenticationOptions{ Authentication: &AuthenticationOptions{ - - Pod: &MetricPipelineRuntimeInputResource{ - - Enabled: boolPtr(true), Basic: &BasicAuthOptions{ Basic: &BasicAuthOptions{ - - }, - - }, User: ValueType{ User: ValueType{ - - }, - - Istio: &MetricPipelineIstioInput{ Value: "user", Value: "user", - - Enabled: boolPtr(true), - - DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ }, }, - - Enabled: boolPtr(true), - - }, Password: ValueType{ Password: ValueType{ - - }, - - OTLP: &OTLPInput{ Value: "pass", Value: "pass", - - Disabled: boolPtr(true), - - }, }, }, - - }, - - }, }, }, - - }, - - }, }, }, - - { - - name: "should convert output section with TLS", }, }, - - input: &telemetryv1beta1.MetricPipeline{ - - Spec: telemetryv1beta1.MetricPipelineSpec{ }, }, - - Output: telemetryv1beta1.MetricPipelineOutput{ - - OTLP: &telemetryv1beta1.OTLPOutput{ }, }, - - Protocol: "grpc", - - Endpoint: telemetryv1beta1.ValueType{ }, }, - - Value: "localhost:4317", - - }, expected: &telemetryv1beta1.MetricPipeline{ expected: &telemetryv1beta1.MetricPipeline{ - - TLS: &telemetryv1beta1.OutputTLS{ - - Disabled: true, Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ - - CA: &telemetryv1beta1.ValueType{ - - Value: "ca-cert", Output: telemetryv1beta1.MetricPipelineOutput{ Output: telemetryv1beta1.MetricPipelineOutput{ - - }, - - Cert: &telemetryv1beta1.ValueType{ OTLP: &telemetryv1beta1.OTLPOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ - - Value: "cert", - - }, Protocol: "grpc", Protocol: "grpc", - - Key: &telemetryv1beta1.ValueType{ - - Value: "key", Endpoint: telemetryv1beta1.ValueType{ Endpoint: telemetryv1beta1.ValueType{ - - }, - - }, Value: "localhost:4317", Value: "localhost:4317", - - }, - - }, }, }, - - }, - - }, Authentication: &telemetryv1beta1.AuthenticationOptions{ Authentication: &telemetryv1beta1.AuthenticationOptions{ - - expected: &MetricPipeline{ - - Spec: MetricPipelineSpec{ Basic: &telemetryv1beta1.BasicAuthOptions{ Basic: &telemetryv1beta1.BasicAuthOptions{ - - Output: MetricPipelineOutput{ - - OTLP: &OTLPOutput{ User: telemetryv1beta1.ValueType{ User: telemetryv1beta1.ValueType{ - - Protocol: "grpc", - - Endpoint: ValueType{ Value: "user", Value: "user", - - Value: "localhost:4317", - - }, }, }, - - TLS: &OTLPTLS{ - - Insecure: true, Password: telemetryv1beta1.ValueType{ Password: telemetryv1beta1.ValueType{ - - CA: &ValueType{ - - Value: "ca-cert", Value: "pass", Value: "pass", - - }, - - Cert: &ValueType{ }, }, - - Value: "cert", - - }, }, }, - - Key: &ValueType{ - - Value: "key", }, }, - - }, - - }, }, }, - - }, - - }, }, }, - - }, - - }, }, }, - - }, - - } }, }, - - - - for _, tt := range tests { }, }, - - t.Run(tt.name, func(t *testing.T) { - - dst := &MetricPipeline{} } } - - err := dst.ConvertFrom(tt.input) - - assert.NoError(t, err) - - assert.Equal(t, tt.expected, dst) - - }) for _, tt := range tests { for _, tt := range tests { - - } - -} t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) { - - - -func TestMetricPipelineConvertToInvalidType(t *testing.T) { dst := &telemetryv1beta1.MetricPipeline{} dst := &telemetryv1beta1.MetricPipeline{} - - src := &MetricPipeline{} - - dst := &MetricPipeline{} // Wrong type, should be v1beta1.MetricPipeline err := tt.input.ConvertTo(dst) err := tt.input.ConvertTo(dst) - - err := src.ConvertTo(dst) - - assert.Error(t, err) assert.NoError(t, err) assert.NoError(t, err) - - assert.Equal(t, errDstTypeUnsupported, err) - -} assert.Equal(t, tt.expected, dst) assert.Equal(t, tt.expected, dst) - - }) }) - - } } - -}} - - - -func TestMetricPipelineConvertFrom(t *testing.T) {func TestMetricPipelineConvertFrom(t *testing.T) { - - tests := []struct { tests := []struct { - - name string name string - - input *telemetryv1beta1.MetricPipeline input *telemetryv1beta1.MetricPipeline - - expected *MetricPipeline expected *MetricPipeline - - }{ }{ - - { { - - name: "should convert basic fields", name: "should convert basic fields", - - input: &telemetryv1beta1.MetricPipeline{ input: &telemetryv1beta1.MetricPipeline{ - - ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ - - Name: "test-pipeline", Name: "test-pipeline", - - Namespace: "test-ns", Namespace: "test-ns", - - }, }, - - Spec: telemetryv1beta1.MetricPipelineSpec{}, Spec: telemetryv1beta1.MetricPipelineSpec{}, - - }, }, - - expected: &MetricPipeline{ expected: &MetricPipeline{ - - ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{ - - Name: "test-pipeline", Name: "test-pipeline", - - Namespace: "test-ns", Namespace: "test-ns", - - }, }, - - Spec: MetricPipelineSpec{}, Spec: MetricPipelineSpec{}, - - }, }, - - }, }, - - { { - - name: "should convert namespaces in namespace selectors without validation", name: "should convert namespaces in namespace selectors without validation", - - input: &telemetryv1beta1.MetricPipeline{ input: &telemetryv1beta1.MetricPipeline{ - - Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ - - Input: telemetryv1beta1.MetricPipelineInput{ Input: telemetryv1beta1.MetricPipelineInput{ - - Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ - - Namespaces: &telemetryv1beta1.NamespaceSelector{ Namespaces: &telemetryv1beta1.NamespaceSelector{ - - Include: []string{"valid-ns", "Invalid_NS"}, Include: []string{"valid-ns", "Invalid_NS"}, - - Exclude: []string{"valid-excluded", "Invalid@NS"}, Exclude: []string{"valid-excluded", "Invalid@NS"}, - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - expected: &MetricPipeline{ expected: &MetricPipeline{ - - Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ - - Input: MetricPipelineInput{ Input: MetricPipelineInput{ - - Runtime: &MetricPipelineRuntimeInput{ Runtime: &MetricPipelineRuntimeInput{ - - Namespaces: &NamespaceSelector{ Namespaces: &NamespaceSelector{ - - Include: []string{"valid-ns", "Invalid_NS"}, Include: []string{"valid-ns", "Invalid_NS"}, - - Exclude: []string{"valid-excluded", "Invalid@NS"}, Exclude: []string{"valid-excluded", "Invalid@NS"}, - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - { { - - name: "should convert all input sections", name: "should convert all input sections", - - input: &telemetryv1beta1.MetricPipeline{ input: &telemetryv1beta1.MetricPipeline{ - - Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ - - Input: telemetryv1beta1.MetricPipelineInput{ Input: telemetryv1beta1.MetricPipelineInput{ - - Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ - - Enabled: boolPtr(true), Enabled: true, - - Namespaces: &telemetryv1beta1.NamespaceSelector{ Namespaces: &telemetryv1beta1.NamespaceSelector{ - - Include: []string{"ns1"}, Include: []string{"ns1"}, - - }, }, - - }, }, - - Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ - - Enabled: boolPtr(true), Enabled: true, - - Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ - - Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ - - Enabled: boolPtr(true), Enabled: true, - - }, }, - - }, }, - - }, }, - - Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Istio: &telemetryv1beta1.MetricPipelineIstioInput{ - - Enabled: boolPtr(true), Enabled: true, - - DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ - - Enabled: boolPtr(true), Enabled: true, - - }, }, - - }, }, - - OTLP: &telemetryv1beta1.OTLPInput{ OTLP: &telemetryv1beta1.OTLPInput{ - - Disabled: boolPtr(true), Disabled: true, - - }, }, - - }, }, - - }, }, - - }, }, - - expected: &MetricPipeline{ expected: &MetricPipeline{ - - Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ - - Input: MetricPipelineInput{ Input: MetricPipelineInput{ - - Prometheus: &MetricPipelinePrometheusInput{ Prometheus: &MetricPipelinePrometheusInput{ - - Enabled: boolPtr(true), Enabled: true, - - Namespaces: &NamespaceSelector{ Namespaces: &NamespaceSelector{ - - Include: []string{"ns1"}, Include: []string{"ns1"}, - - }, }, - - }, }, - - Runtime: &MetricPipelineRuntimeInput{ Runtime: &MetricPipelineRuntimeInput{ - - Enabled: boolPtr(true), Enabled: true, - - Resources: &MetricPipelineRuntimeInputResources{ Resources: &MetricPipelineRuntimeInputResources{ - - Pod: &MetricPipelineRuntimeInputResource{ Pod: &MetricPipelineRuntimeInputResource{ - - Enabled: boolPtr(true), Enabled: true, - - }, }, - - }, }, - - }, }, - - Istio: &MetricPipelineIstioInput{ Istio: &MetricPipelineIstioInput{ - - Enabled: boolPtr(true), Enabled: true, - - DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ DiagnosticMetrics: &MetricPipelineIstioInputDiagnosticMetrics{ - - Enabled: boolPtr(true), Enabled: true, - - }, }, - - }, }, - - OTLP: &OTLPInput{ OTLP: &OTLPInput{ - - Disabled: boolPtr(true), Disabled: true, - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - { { - - name: "should convert output section with TLS", name: "should convert output section with TLS", - - input: &telemetryv1beta1.MetricPipeline{ input: &telemetryv1beta1.MetricPipeline{ - - Spec: telemetryv1beta1.MetricPipelineSpec{ Spec: telemetryv1beta1.MetricPipelineSpec{ - - Output: telemetryv1beta1.MetricPipelineOutput{ Output: telemetryv1beta1.MetricPipelineOutput{ - - OTLP: &telemetryv1beta1.OTLPOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ - - Protocol: "grpc", Protocol: "grpc", - - Endpoint: telemetryv1beta1.ValueType{ Endpoint: telemetryv1beta1.ValueType{ - - Value: "localhost:4317", Value: "localhost:4317", - - }, }, - - TLS: &telemetryv1beta1.OutputTLS{ TLS: &telemetryv1beta1.OutputTLS{ - - Disabled: true, Disabled: true, - - CA: &telemetryv1beta1.ValueType{ CA: &telemetryv1beta1.ValueType{ - - Value: "ca-cert", Value: "ca-cert", - - }, }, - - Cert: &telemetryv1beta1.ValueType{ Cert: &telemetryv1beta1.ValueType{ - - Value: "cert", Value: "cert", - - }, }, - - Key: &telemetryv1beta1.ValueType{ Key: &telemetryv1beta1.ValueType{ - - Value: "key", Value: "key", - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - expected: &MetricPipeline{ expected: &MetricPipeline{ - - Spec: MetricPipelineSpec{ Spec: MetricPipelineSpec{ - - Output: MetricPipelineOutput{ Output: MetricPipelineOutput{ - - OTLP: &OTLPOutput{ OTLP: &OTLPOutput{ - - Protocol: "grpc", Protocol: "grpc", - - Endpoint: ValueType{ Endpoint: ValueType{ - - Value: "localhost:4317", Value: "localhost:4317", - - }, }, - - TLS: &OTLPTLS{ TLS: &OTLPTLS{ - - Insecure: true, Insecure: true, - - CA: &ValueType{ CA: &ValueType{ - - Value: "ca-cert", Value: "ca-cert", - - }, }, - - Cert: &ValueType{ Cert: &ValueType{ - - Value: "cert", Value: "cert", - - }, }, - - Key: &ValueType{ Key: &ValueType{ - - Value: "key", Value: "key", - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - }, }, - - } } - - - - for _, tt := range tests { for _, tt := range tests { - - t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) { - - dst := &MetricPipeline{} dst := &MetricPipeline{} - - err := dst.ConvertFrom(tt.input) err := dst.ConvertFrom(tt.input) - - assert.NoError(t, err) assert.NoError(t, err) - - assert.Equal(t, tt.expected, dst) assert.Equal(t, tt.expected, dst) - - }) }) - - } } - -}} - - - -func TestMetricPipelineConvertToInvalidType(t *testing.T) {func TestMetricPipelineConvertToInvalidType(t *testing.T) { - - src := &MetricPipeline{} src := &MetricPipeline{} - - dst := &MetricPipeline{} // Wrong type, should be v1beta1.MetricPipeline dst := &MetricPipeline{} // Wrong type, should be v1beta1.MetricPipeline - - err := src.ConvertTo(dst) err := src.ConvertTo(dst) - - assert.Error(t, err) assert.Error(t, err) - - assert.Equal(t, errDstTypeUnsupported, err) assert.Equal(t, errDstTypeUnsupported, err) - -}} \ No newline at end of file diff --git a/apis/telemetry/v1alpha1/shared_types_conversion.go b/apis/telemetry/v1alpha1/shared_types_conversion.go index 8849fd42db..59f995115e 100644 --- a/apis/telemetry/v1alpha1/shared_types_conversion.go +++ b/apis/telemetry/v1alpha1/shared_types_conversion.go @@ -16,6 +16,7 @@ func sanitizeNamespaceNames(names []string) []string { valid = append(valid, n) } } + return valid } @@ -23,8 +24,269 @@ func convertNamespaceSelectorToBeta(ns *NamespaceSelector) *telemetryv1beta1.Nam if ns == nil { return nil } + return &telemetryv1beta1.NamespaceSelector{ Include: sanitizeNamespaceNames(ns.Include), Exclude: sanitizeNamespaceNames(ns.Exclude), } } + +func convertNamespaceSelectorToAlpha(ns *telemetryv1beta1.NamespaceSelector) *NamespaceSelector { + if ns == nil { + return nil + } + + return &NamespaceSelector{ + Include: append([]string{}, ns.Include...), + Exclude: append([]string{}, ns.Exclude...), + } +} + +func convertOTLPOutputToBeta(o *OTLPOutput) *telemetryv1beta1.OTLPOutput { + if o == nil { + return nil + } + + return &telemetryv1beta1.OTLPOutput{ + Protocol: telemetryv1beta1.OTLPProtocol(o.Protocol), + Endpoint: convertValueTypeToBeta(o.Endpoint), + Path: o.Path, + Authentication: convertAuthenticationToBeta(o.Authentication), + Headers: convertHeadersToBeta(o.Headers), + TLS: convertOTLPTLSToBeta(o.TLS), + } +} + +func convertOTLPOutputToAlpha(o *telemetryv1beta1.OTLPOutput) *OTLPOutput { + if o == nil { + return nil + } + + return &OTLPOutput{ + Protocol: string(o.Protocol), + Endpoint: convertValueTypeToAlpha(o.Endpoint), + Path: o.Path, + Authentication: convertAuthenticationToAlpha(o.Authentication), + Headers: convertHeadersToAlpha(o.Headers), + TLS: convertOTLPTLSToAlpha(o.TLS), + } +} + +func convertValueTypeToBeta(v ValueType) telemetryv1beta1.ValueType { + result := telemetryv1beta1.ValueType{ + Value: v.Value, + } + + if v.ValueFrom != nil && v.ValueFrom.SecretKeyRef != nil { + result.ValueFrom = convertValueFromSourceToBeta(v.ValueFrom) + } + + return result +} + +func convertValueTypeToAlpha(v telemetryv1beta1.ValueType) ValueType { + result := ValueType{ + Value: v.Value, + } + if v.ValueFrom != nil && v.ValueFrom.SecretKeyRef != nil { + result.ValueFrom = convertValueFromSourceToAlpha(v.ValueFrom) + } + + return result +} + +func convertValueFromSourceToBeta(v *ValueFromSource) *telemetryv1beta1.ValueFromSource { + if v == nil { + return nil + } + + return &telemetryv1beta1.ValueFromSource{ + SecretKeyRef: convertSecretKeyRefToBeta(v.SecretKeyRef), + } +} + +func convertValueFromSourceToAlpha(v *telemetryv1beta1.ValueFromSource) *ValueFromSource { + if v == nil { + return nil + } + + return &ValueFromSource{ + SecretKeyRef: convertSecretKeyRefToAlpha(v.SecretKeyRef), + } +} + +func convertSecretKeyRefToBeta(s *SecretKeyRef) *telemetryv1beta1.SecretKeyRef { + if s == nil { + return nil + } + + return &telemetryv1beta1.SecretKeyRef{ + Name: s.Name, + Namespace: s.Namespace, + Key: s.Key, + } +} + +func convertSecretKeyRefToAlpha(s *telemetryv1beta1.SecretKeyRef) *SecretKeyRef { + if s == nil { + return nil + } + + return &SecretKeyRef{ + Name: s.Name, + Namespace: s.Namespace, + Key: s.Key, + } +} + +func convertAuthenticationToBeta(a *AuthenticationOptions) *telemetryv1beta1.AuthenticationOptions { + if a == nil { + return nil + } + + return &telemetryv1beta1.AuthenticationOptions{ + Basic: convertBasicAuthToBeta(a.Basic), + } +} + +func convertAuthenticationToAlpha(a *telemetryv1beta1.AuthenticationOptions) *AuthenticationOptions { + if a == nil { + return nil + } + + return &AuthenticationOptions{ + Basic: convertBasicAuthToAlpha(a.Basic), + } +} + +func convertBasicAuthToBeta(b *BasicAuthOptions) *telemetryv1beta1.BasicAuthOptions { + if b == nil { + return nil + } + + return &telemetryv1beta1.BasicAuthOptions{ + User: convertValueTypeToBeta(b.User), + Password: convertValueTypeToBeta(b.Password), + } +} + +func convertBasicAuthToAlpha(b *telemetryv1beta1.BasicAuthOptions) *BasicAuthOptions { + if b == nil { + return nil + } + + return &BasicAuthOptions{ + User: convertValueTypeToAlpha(b.User), + Password: convertValueTypeToAlpha(b.Password), + } +} + +func convertHeadersToBeta(hs []Header) []telemetryv1beta1.Header { + var out []telemetryv1beta1.Header + for _, h := range hs { + out = append(out, telemetryv1beta1.Header{ + ValueType: convertValueTypeToBeta(h.ValueType), + Name: h.Name, + Prefix: h.Prefix, + }) + } + + return out +} + +func convertHeadersToAlpha(hs []telemetryv1beta1.Header) []Header { + var out []Header + for _, h := range hs { + out = append(out, Header{ + ValueType: convertValueTypeToAlpha(h.ValueType), + Name: h.Name, + Prefix: h.Prefix, + }) + } + + return out +} + +func convertOTLPTLSToBeta(t *OTLPTLS) *telemetryv1beta1.OutputTLS { + if t == nil { + return nil + } + + return &telemetryv1beta1.OutputTLS{ + Disabled: t.Insecure, + SkipCertificateValidation: t.InsecureSkipVerify, + CA: convertValueTypeToBetaPtr(t.CA), + Cert: convertValueTypeToBetaPtr(t.Cert), + Key: convertValueTypeToBetaPtr(t.Key), + } +} + +func convertOTLPTLSToAlpha(t *telemetryv1beta1.OutputTLS) *OTLPTLS { + if t == nil { + return nil + } + + return &OTLPTLS{ + Insecure: t.Disabled, + InsecureSkipVerify: t.SkipCertificateValidation, + CA: convertValueTypeToAlphaPtr(t.CA), + Cert: convertValueTypeToAlphaPtr(t.Cert), + Key: convertValueTypeToAlphaPtr(t.Key), + } +} + +func convertValueTypeToBetaPtr(v *ValueType) *telemetryv1beta1.ValueType { + if v == nil { + return nil + } + + vt := convertValueTypeToBeta(*v) + + return &vt +} + +func convertValueTypeToAlphaPtr(v *telemetryv1beta1.ValueType) *ValueType { + if v == nil { + return nil + } + + vt := convertValueTypeToAlpha(*v) + + return &vt +} + +func convertTransformSpecToBeta(src TransformSpec) telemetryv1beta1.TransformSpec { + var dst telemetryv1beta1.TransformSpec + + dst.Conditions = append(dst.Conditions, src.Conditions...) + + dst.Statements = append(dst.Statements, src.Statements...) + + return dst +} + +func convertTransformSpecToAlpha(src telemetryv1beta1.TransformSpec) TransformSpec { + var dst TransformSpec + + dst.Conditions = append(dst.Conditions, src.Conditions...) + + dst.Statements = append(dst.Statements, src.Statements...) + + return dst +} + +func convertFilterSpecToBeta(src FilterSpec) telemetryv1beta1.FilterSpec { + var dst telemetryv1beta1.FilterSpec + + dst.Conditions = append(dst.Conditions, src.Conditions...) + + return dst +} + +func convertFilterSpecToAlpha(src telemetryv1beta1.FilterSpec) FilterSpec { + var dst FilterSpec + + dst.Conditions = append(dst.Conditions, src.Conditions...) + + return dst +} diff --git a/apis/telemetry/v1beta1/logpipeline_types.go b/apis/telemetry/v1beta1/logpipeline_types.go index 04674b2a60..90cc8a0c54 100644 --- a/apis/telemetry/v1beta1/logpipeline_types.go +++ b/apis/telemetry/v1beta1/logpipeline_types.go @@ -113,9 +113,9 @@ type LogPipelineRuntimeInput struct { // If enabled, application logs are collected from application containers stdout/stderr. The default is `true`. // +kubebuilder:validation:Optional Enabled *bool `json:"enabled,omitempty"` - // Namespaces describes whether application logs from specific namespaces are selected. The options are mutually exclusive. System namespaces are excluded by default. Use the `system` attribute with value `true` to enable them. + // Namespaces describes whether application logs from specific namespaces are selected. The options are mutually exclusive. By default, all namespaces except the system namespaces are enabled. To enable all namespaces including system namespaces, use an empty struct notation. // +kubebuilder:validation:Optional - Namespaces LogPipelineNamespaceSelector `json:"namespaces,omitempty"` + Namespaces *NamespaceSelector `json:"namespaces,omitempty"` // Containers describes whether application logs from specific containers are selected. The options are mutually exclusive. // +kubebuilder:validation:Optional Containers LogPipelineContainerSelector `json:"containers,omitempty"` diff --git a/apis/telemetry/v1beta1/metricpipeline_types.go b/apis/telemetry/v1beta1/metricpipeline_types.go index 6f9248770c..baa67914a2 100644 --- a/apis/telemetry/v1beta1/metricpipeline_types.go +++ b/apis/telemetry/v1beta1/metricpipeline_types.go @@ -74,7 +74,7 @@ type MetricPipelineSpec struct { // Filter specifies a list of filters to apply to telemetry data. // +kubebuilder:validation:Optional - Filter []FilterSpec `json:"filter,omitempty"` + Filters []FilterSpec `json:"filter,omitempty"` } // MetricPipelineInput configures additional inputs for metric collection. diff --git a/apis/telemetry/v1beta1/shared_types.go b/apis/telemetry/v1beta1/shared_types.go index e69e8fc18a..5d56aab592 100644 --- a/apis/telemetry/v1beta1/shared_types.go +++ b/apis/telemetry/v1beta1/shared_types.go @@ -115,9 +115,9 @@ type OutputTLS struct { // OTLPInput defines the collection of push-based metrics that use the OpenTelemetry protocol. type OTLPInput struct { - // If set to `true`, no push-based OTLP signals are collected. The default is `false`. + // If set to `false`, no push-based OTLP signals are collected. The default is `true`. // +kubebuilder:validation:Optional - Disabled bool `json:"disabled,omitempty"` + Enabled *bool `json:"disabled,omitempty"` // Namespaces describes whether push-based OTLP signals from specific namespaces are selected. System namespaces are enabled by default. // +kubebuilder:validation:Optional Namespaces *NamespaceSelector `json:"namespaces,omitempty"` diff --git a/apis/telemetry/v1beta1/zz_generated.deepcopy.go b/apis/telemetry/v1beta1/zz_generated.deepcopy.go index b0efc41973..29eb9888c8 100644 --- a/apis/telemetry/v1beta1/zz_generated.deepcopy.go +++ b/apis/telemetry/v1beta1/zz_generated.deepcopy.go @@ -342,7 +342,11 @@ func (in *LogPipelineRuntimeInput) DeepCopyInto(out *LogPipelineRuntimeInput) { *out = new(bool) **out = **in } - in.Namespaces.DeepCopyInto(&out.Namespaces) + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = new(NamespaceSelector) + (*in).DeepCopyInto(*out) + } in.Containers.DeepCopyInto(&out.Containers) if in.KeepAnnotations != nil { in, out := &in.KeepAnnotations, &out.KeepAnnotations @@ -778,8 +782,8 @@ func (in *MetricPipelineSpec) DeepCopyInto(out *MetricPipelineSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.Filter != nil { - in, out := &in.Filter, &out.Filter + if in.Filters != nil { + in, out := &in.Filters, &out.Filters *out = make([]FilterSpec, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) @@ -847,6 +851,11 @@ func (in *NamespaceSelector) DeepCopy() *NamespaceSelector { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OTLPInput) DeepCopyInto(out *OTLPInput) { *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } if in.Namespaces != nil { in, out := &in.Namespaces, &out.Namespaces *out = new(NamespaceSelector) diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml index 77e4117b25..6a75206276 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml @@ -1237,8 +1237,8 @@ spec: logs from a OTLP source. properties: disabled: - description: If set to `true`, no push-based OTLP signals - are collected. The default is `false`. + description: If set to `false`, no push-based OTLP signals + are collected. The default is `true`. type: boolean namespaces: description: Namespaces describes whether push-based OTLP @@ -1315,35 +1315,27 @@ spec: namespaces: description: Namespaces describes whether application logs from specific namespaces are selected. The options are mutually - exclusive. System namespaces are excluded by default. Use - the `system` attribute with value `true` to enable them. + exclusive. By default, all namespaces except the system + namespaces are enabled. To enable all namespaces including + system namespaces, use an empty struct notation. properties: exclude: - description: Exclude the container logs of the specified - Namespace names. + description: Exclude signals from the specified Namespace + names only. items: type: string type: array include: - description: Include only the container logs of the specified - Namespace names. + description: Include signals from the specified Namespace + names only. items: type: string type: array - system: - description: System specifies whether to collect logs - from system namespaces. If set to `true`, you collect - logs from all namespaces including system namespaces, - such as like kube-system, istio-system, and kyma-system. - The default is `false`. - type: boolean type: object x-kubernetes-validations: - - message: Only one of 'include', 'exclude' or 'system' can - be defined + - message: Only one of 'include' or 'exclude' can be defined rule: '(has(self.include) == true ? 1 : 0) + (has(self.exclude) - == true ? 1 : 0) + (has(self.system) == true ? 1 : 0) - <= 1' + == true ? 1 : 0) <= 1' type: object type: object output: diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml index 688b6a58d0..6f9fba2166 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml @@ -927,8 +927,8 @@ spec: metrics from an OTLP source. properties: disabled: - description: If set to `true`, no push-based OTLP signals - are collected. The default is `false`. + description: If set to `false`, no push-based OTLP signals + are collected. The default is `true`. type: boolean namespaces: description: Namespaces describes whether push-based OTLP diff --git a/internal/utils/test/log_pipeline_builder.go b/internal/utils/test/log_pipeline_builder.go index e1f056ad42..a15ed9f3c4 100644 --- a/internal/utils/test/log_pipeline_builder.go +++ b/internal/utils/test/log_pipeline_builder.go @@ -80,7 +80,7 @@ func BuildLogPipelineV1Beta1RuntimeInput() telemetryv1beta1.LogPipelineInput { input := telemetryv1beta1.LogPipelineInput{ Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: ptr.To(true), - Namespaces: telemetryv1beta1.LogPipelineNamespaceSelector{}, + Namespaces: &telemetryv1beta1.NamespaceSelector{}, }, } @@ -93,7 +93,7 @@ func BuildLogPipelineV1Beta1OTLPInput() telemetryv1beta1.LogPipelineInput { Enabled: ptr.To(false), }, OTLP: &telemetryv1beta1.OTLPInput{ - Disabled: false, + Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{}, }, } diff --git a/main.go b/main.go index 9553134bd3..db24c92bcd 100644 --- a/main.go +++ b/main.go @@ -396,6 +396,7 @@ func setupLogPipelineController(mgr manager.Manager, reconcileTriggerChan <-chan if featureflags.IsEnabled(featureflags.V1Beta1) { setupLog.Info("Registering conversion webhooks for LogPipelines") utilruntime.Must(telemetryv1beta1.AddToScheme(scheme)) + if err := ctrl.NewWebhookManagedBy(mgr). For(&telemetryv1alpha1.LogPipeline{}). Complete(); err != nil { @@ -409,6 +410,7 @@ func setupLogPipelineController(mgr manager.Manager, reconcileTriggerChan <-chan } setupLog.Info("Registering conversion webhooks for MetricPipelines") + if err := ctrl.NewWebhookManagedBy(mgr). For(&telemetryv1alpha1.MetricPipeline{}). Complete(); err != nil { diff --git a/test/e2e/metrics/shared/single_pipeline_v1beta1_test.go b/test/e2e/metrics/shared/single_pipeline_v1beta1_test.go index 68f69ceb4e..8b7d0fdf99 100644 --- a/test/e2e/metrics/shared/single_pipeline_v1beta1_test.go +++ b/test/e2e/metrics/shared/single_pipeline_v1beta1_test.go @@ -46,9 +46,7 @@ func TestSinglePipelineV1Beta1(t *testing.T) { { label: suite.LabelMetricGatewaySetC, input: telemetryv1beta1.MetricPipelineInput{ - OTLP: &telemetryv1beta1.OTLPInput{ - Disabled: false, - }, + OTLP: &telemetryv1beta1.OTLPInput{}, }, generatorBuilder: func(ns string) []client.Object { return []client.Object{ diff --git a/webhook/logpipeline/v1beta1/defaulter.go b/webhook/logpipeline/v1beta1/defaulter.go index dccf234e51..a8225eb136 100644 --- a/webhook/logpipeline/v1beta1/defaulter.go +++ b/webhook/logpipeline/v1beta1/defaulter.go @@ -14,9 +14,11 @@ import ( var _ webhook.CustomDefaulter = &defaulter{} type defaulter struct { + ExcludeNamespaces []string RuntimeInputEnabled bool RuntimeInputKeepOriginalBody bool DefaultOTLPOutputProtocol telemetryv1beta1.OTLPProtocol + OTLPInputEnabled bool } func (ld defaulter) Default(ctx context.Context, obj runtime.Object) error { @@ -39,9 +41,22 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1beta1.LogPipeline) { if *pipeline.Spec.Input.Runtime.Enabled && pipeline.Spec.Input.Runtime.KeepOriginalBody == nil { pipeline.Spec.Input.Runtime.KeepOriginalBody = &ld.RuntimeInputKeepOriginalBody } + if *pipeline.Spec.Input.Runtime.Enabled && pipeline.Spec.Input.Runtime.Namespaces == nil { + pipeline.Spec.Input.Runtime.Namespaces = &telemetryv1beta1.NamespaceSelector{ + Exclude: ld.ExcludeNamespaces, + } + } } if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { pipeline.Spec.Output.OTLP.Protocol = ld.DefaultOTLPOutputProtocol } + + if pipeline.Spec.Input.OTLP == nil { + pipeline.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{} + } + + if pipeline.Spec.Input.OTLP.Enabled == nil { + pipeline.Spec.Input.OTLP.Enabled = &ld.OTLPInputEnabled + } } diff --git a/webhook/logpipeline/v1beta1/defaulter_test.go b/webhook/logpipeline/v1beta1/defaulter_test.go index c34ffcde1c..7acc05c981 100644 --- a/webhook/logpipeline/v1beta1/defaulter_test.go +++ b/webhook/logpipeline/v1beta1/defaulter_test.go @@ -11,9 +11,11 @@ import ( func TestDefault(t *testing.T) { sut := defaulter{ + ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, RuntimeInputEnabled: true, RuntimeInputKeepOriginalBody: true, DefaultOTLPOutputProtocol: telemetryv1beta1.OTLPProtocolGRPC, + OTLPInputEnabled: true, } tests := []struct { @@ -33,9 +35,15 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: ptr.To(true), KeepOriginalBody: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + }, }, }, }, @@ -55,9 +63,15 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: ptr.To(true), KeepOriginalBody: ptr.To(false), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + }, }, }, }, @@ -77,6 +91,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: ptr.To(false), }, @@ -95,6 +112,11 @@ func TestDefault(t *testing.T) { }, expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, + }, Output: telemetryv1beta1.LogPipelineOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ Protocol: telemetryv1beta1.OTLPProtocolGRPC, @@ -103,6 +125,19 @@ func TestDefault(t *testing.T) { }, }, }, + { + name: "should enable otlp input by default", + input: &telemetryv1beta1.LogPipeline{}, + expected: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, + }, + }, + }, + }, } for _, tt := range tests { diff --git a/webhook/logpipeline/v1beta1/setup.go b/webhook/logpipeline/v1beta1/setup.go index 1511888999..b655095cc5 100644 --- a/webhook/logpipeline/v1beta1/setup.go +++ b/webhook/logpipeline/v1beta1/setup.go @@ -9,9 +9,11 @@ import ( func SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr).For(&telemetryv1beta1.LogPipeline{}). WithDefaulter(&defaulter{ + ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, RuntimeInputEnabled: true, RuntimeInputKeepOriginalBody: true, DefaultOTLPOutputProtocol: telemetryv1beta1.OTLPProtocolGRPC, + OTLPInputEnabled: true, }). Complete() } diff --git a/webhook/metricpipeline/v1beta1/defaulter.go b/webhook/metricpipeline/v1beta1/defaulter.go index cf4b7fef28..08072cc122 100644 --- a/webhook/metricpipeline/v1beta1/defaulter.go +++ b/webhook/metricpipeline/v1beta1/defaulter.go @@ -15,6 +15,7 @@ var _ webhook.CustomDefaulter = &defaulter{} type defaulter struct { ExcludeNamespaces []string + OTLPInputEnabled bool RuntimeInputResources runtimeInputResourceDefaults DefaultOTLPOutputProtocol telemetryv1beta1.OTLPProtocol DiagnosticMetricsEnabled bool @@ -87,6 +88,14 @@ func (md defaulter) applyDefaults(pipeline *telemetryv1beta1.MetricPipeline) { Enabled: &md.DiagnosticMetricsEnabled, } } + + if pipeline.Spec.Input.OTLP == nil { + pipeline.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{} + } + + if pipeline.Spec.Input.OTLP.Enabled == nil { + pipeline.Spec.Input.OTLP.Enabled = &md.OTLPInputEnabled + } } func (md defaulter) applyRuntimeInputResourceDefaults(pipeline *telemetryv1beta1.MetricPipeline) { diff --git a/webhook/metricpipeline/v1beta1/defaulter_test.go b/webhook/metricpipeline/v1beta1/defaulter_test.go index 17e8e5d6fc..ac4062f88a 100644 --- a/webhook/metricpipeline/v1beta1/defaulter_test.go +++ b/webhook/metricpipeline/v1beta1/defaulter_test.go @@ -12,6 +12,7 @@ import ( func TestDefault(t *testing.T) { sut := defaulter{ ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + OTLPInputEnabled: true, RuntimeInputResources: runtimeInputResourceDefaults{ Pod: true, Container: true, @@ -41,6 +42,11 @@ func TestDefault(t *testing.T) { }, expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ + Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, + }, Output: telemetryv1beta1.MetricPipelineOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ Protocol: telemetryv1beta1.OTLPProtocolGRPC, @@ -62,6 +68,11 @@ func TestDefault(t *testing.T) { }, expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ + Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, + }, Output: telemetryv1beta1.MetricPipelineOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ Protocol: telemetryv1beta1.OTLPProtocolHTTP, @@ -84,6 +95,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ @@ -111,6 +125,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ @@ -142,6 +159,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ @@ -205,6 +225,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ @@ -262,6 +285,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(false), }, @@ -269,6 +295,19 @@ func TestDefault(t *testing.T) { }, }, }, + { + name: "should enable otlp input by default", + input: &telemetryv1beta1.MetricPipeline{}, + expected: &telemetryv1beta1.MetricPipeline{ + Spec: telemetryv1beta1.MetricPipelineSpec{ + Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, + }, + }, + }, + }, { name: "should not set defaults for Istio input", input: &telemetryv1beta1.MetricPipeline{ @@ -283,6 +322,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(false), }, @@ -304,6 +346,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(false), }, @@ -328,6 +373,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ @@ -359,6 +407,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ @@ -390,6 +441,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(true), + }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ diff --git a/webhook/metricpipeline/v1beta1/setup.go b/webhook/metricpipeline/v1beta1/setup.go index bcd4f5846e..ea8ccc10d5 100644 --- a/webhook/metricpipeline/v1beta1/setup.go +++ b/webhook/metricpipeline/v1beta1/setup.go @@ -20,6 +20,7 @@ func SetupWithManager(mgr ctrl.Manager) error { StatefulSet: true, Job: true, }, + OTLPInputEnabled: true, DefaultOTLPOutputProtocol: telemetryv1beta1.OTLPProtocolGRPC, DiagnosticMetricsEnabled: false, EnvoyMetricsEnabled: false, From 2a6a1f9f1eacfae0baf8228e98610f9f59fe4c4f Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Fri, 17 Oct 2025 19:11:23 +0200 Subject: [PATCH 03/27] fix --- go.mod | 2 +- webhook/logpipeline/v1beta1/defaulter.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 434b74ceaa..fd188eb063 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.25.3 require ( github.com/go-logr/logr v1.4.3 github.com/go-logr/zapr v1.3.0 - github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 github.com/onsi/gomega v1.38.2 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.136.0 @@ -55,6 +54,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect diff --git a/webhook/logpipeline/v1beta1/defaulter.go b/webhook/logpipeline/v1beta1/defaulter.go index a8225eb136..8bbe228e8c 100644 --- a/webhook/logpipeline/v1beta1/defaulter.go +++ b/webhook/logpipeline/v1beta1/defaulter.go @@ -41,6 +41,7 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1beta1.LogPipeline) { if *pipeline.Spec.Input.Runtime.Enabled && pipeline.Spec.Input.Runtime.KeepOriginalBody == nil { pipeline.Spec.Input.Runtime.KeepOriginalBody = &ld.RuntimeInputKeepOriginalBody } + if *pipeline.Spec.Input.Runtime.Enabled && pipeline.Spec.Input.Runtime.Namespaces == nil { pipeline.Spec.Input.Runtime.Namespaces = &telemetryv1beta1.NamespaceSelector{ Exclude: ld.ExcludeNamespaces, From 18ef1300b6f9b5eee735031f58081e87aa82add1 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 09:52:48 +0200 Subject: [PATCH 04/27] fix log line --- internal/webhookcert/resources.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/webhookcert/resources.go b/internal/webhookcert/resources.go index a8bf3d8d9a..9ac62eb488 100644 --- a/internal/webhookcert/resources.go +++ b/internal/webhookcert/resources.go @@ -75,7 +75,7 @@ func makeConversionWebhookConfig(caBundle []byte, config Config) apiextensionsv1 func updatePipelineCRDWithConversionWebhookConfig(ctx context.Context, c client.Client, pipelineType types.NamespacedName, conversion apiextensionsv1.CustomResourceConversion) error { var crd apiextensionsv1.CustomResourceDefinition if err := c.Get(ctx, pipelineType, &crd); err != nil { - return fmt.Errorf("failed to get logpipelines CRD: %w", err) + return fmt.Errorf("failed to get CRD %s: %w", pipelineType, err) } crd.Spec.Conversion = &conversion From df6d1474a52ea56d0adb2f44b8dd4043cacfaf1e Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 16:00:13 +0200 Subject: [PATCH 05/27] switch TLS Disabled to TLS Insecure --- .../v1alpha1/logpipeline_conversion.go | 151 ++++++++++-------- .../v1alpha1/logpipeline_conversion_test.go | 14 +- .../v1alpha1/metricpipeline_conversion.go | 12 +- .../metricpipeline_conversion_test.go | 12 +- .../v1alpha1/shared_types_conversion.go | 38 ++++- apis/telemetry/v1beta1/shared_types.go | 8 +- ...elemetry.kyma-project.io_logpipelines.yaml | 28 ++-- ...metry.kyma-project.io_metricpipelines.yaml | 14 +- ...emetry.kyma-project.io_tracepipelines.yaml | 14 +- internal/webhookcert/webhook_cert_test.go | 110 ++++++++----- test/e2e/logs/misc/version_conversion_test.go | 2 +- .../shared/single_pipeline_v1beta1_test.go | 8 +- webhook/metricpipeline/v1beta1/defaulter.go | 62 +++---- 13 files changed, 274 insertions(+), 199 deletions(-) diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index 59d7f82f7c..dfc74946d8 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -3,7 +3,6 @@ package v1alpha1 import ( "errors" - "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/conversion" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" @@ -24,17 +23,21 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { // Copy metadata dst.ObjectMeta = src.ObjectMeta - // Copy Spec fields + // Copy Input fields dst.Spec.Input = telemetryv1beta1.LogPipelineInput{} dst.Spec.Input.Runtime = convertApplicationToBeta(src.Spec.Input.Application) + dst.Spec.Input.OTLP = convertOTLPInputToBeta(src.Spec.Input.OTLP) - if src.Spec.Input.OTLP != nil { - dst.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(!src.Spec.Input.OTLP.Disabled), - Namespaces: convertNamespaceSelectorToBeta(src.Spec.Input.OTLP.Namespaces), - } + // Copy Output fields + dst.Spec.Output = telemetryv1beta1.LogPipelineOutput{} + dst.Spec.Output.HTTP = convertHTTPOutputToBeta(src.Spec.Output.HTTP) + + dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) + if src.Spec.Output.Custom != "" { + dst.Spec.Output.Custom = src.Spec.Output.Custom } + // Copy everything else for _, f := range src.Spec.Files { dst.Spec.Files = append(dst.Spec.Files, telemetryv1beta1.LogPipelineFileMount(f)) } @@ -43,36 +46,6 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { dst.Spec.FluentBitFilters = append(dst.Spec.FluentBitFilters, telemetryv1beta1.LogPipelineFilter(f)) } - if srcHTTPOutput := src.Spec.Output.HTTP; srcHTTPOutput != nil { - dst.Spec.Output.HTTP = &telemetryv1beta1.LogPipelineHTTPOutput{ - Host: convertValueTypeToBeta(srcHTTPOutput.Host), - URI: srcHTTPOutput.URI, - Port: srcHTTPOutput.Port, - Compress: srcHTTPOutput.Compress, - Format: srcHTTPOutput.Format, - TLSConfig: convertOutputTLSToBeta(srcHTTPOutput.TLS), - Dedot: srcHTTPOutput.Dedot, - } - - if srcHTTPOutput.User != nil && (srcHTTPOutput.User.Value != "" || srcHTTPOutput.User.ValueFrom != nil) { - user := convertValueTypeToBeta(*srcHTTPOutput.User) - dst.Spec.Output.HTTP.User = &user - } - - if srcHTTPOutput.Password != nil && (srcHTTPOutput.Password.Value != "" || srcHTTPOutput.Password.ValueFrom != nil) { - password := convertValueTypeToBeta(*srcHTTPOutput.Password) - dst.Spec.Output.HTTP.Password = &password - } - } - - if src.Spec.Output.OTLP != nil { - dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) - } - - if srcCustomOutput := src.Spec.Output.Custom; srcCustomOutput != "" { - dst.Spec.Output.Custom = srcCustomOutput - } - if src.Spec.Transforms != nil { for _, t := range src.Spec.Transforms { dst.Spec.Transforms = append(dst.Spec.Transforms, convertTransformSpecToBeta(t)) @@ -90,6 +63,34 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { return nil } +func convertHTTPOutputToBeta(output *LogPipelineHTTPOutput) *telemetryv1beta1.LogPipelineHTTPOutput { + if output == nil { + return nil + } + + result := &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: convertValueTypeToBeta(output.Host), + URI: output.URI, + Port: output.Port, + Compress: output.Compress, + Format: output.Format, + TLSConfig: convertOutputTLSToBeta(output.TLS), + Dedot: output.Dedot, + } + + if output.User != nil && (output.User.Value != "" || output.User.ValueFrom != nil) { + user := convertValueTypeToBeta(*output.User) + result.User = &user + } + + if output.Password != nil && (output.Password.Value != "" || output.Password.ValueFrom != nil) { + password := convertValueTypeToBeta(*output.Password) + result.Password = &password + } + + return result +} + func convertApplicationToBeta(application *LogPipelineApplicationInput) *telemetryv1beta1.LogPipelineRuntimeInput { if application == nil { return nil @@ -126,8 +127,8 @@ func convertOutputTLSToBeta(src LogPipelineOutputTLS) telemetryv1beta1.OutputTLS dst.CA = convertValueTypeToBetaPtr(src.CA) dst.Cert = convertValueTypeToBetaPtr(src.Cert) dst.Key = convertValueTypeToBetaPtr(src.Key) - dst.Disabled = src.Disabled - dst.SkipCertificateValidation = src.SkipCertificateValidation + dst.Insecure = src.Disabled + dst.InsecureSkipVerify = src.SkipCertificateValidation return dst } @@ -144,16 +145,21 @@ func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { // Copy metadata dst.ObjectMeta = src.ObjectMeta - // Copy Spec fields + // Copy input fields + dst.Spec.Input = LogPipelineInput{} dst.Spec.Input.Application = convertRuntimeToAlpha(src.Spec.Input.Runtime) + dst.Spec.Input.OTLP = convertOTLPInputToAlpha(src.Spec.Input.OTLP) - if src.Spec.Input.OTLP != nil { - dst.Spec.Input.OTLP = &OTLPInput{ - Disabled: src.Spec.Input.OTLP.Enabled != nil && !*src.Spec.Input.OTLP.Enabled, - Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.OTLP.Namespaces), - } + // Copy output fields + dst.Spec.Output = LogPipelineOutput{} + dst.Spec.Output.HTTP = convertHTTPOutputToAlpha(src.Spec.Output.HTTP) + dst.Spec.Output.OTLP = convertOTLPOutputToAlpha(src.Spec.Output.OTLP) + + if src.Spec.Output.Custom != "" { + dst.Spec.Output.Custom = src.Spec.Output.Custom } + // Copy everything else for _, f := range src.Spec.Files { dst.Spec.Files = append(dst.Spec.Files, LogPipelineFileMount(f)) } @@ -162,29 +168,6 @@ func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { dst.Spec.FluentBitFilters = append(dst.Spec.FluentBitFilters, LogPipelineFilter(f)) } - if srcHTTPOutput := src.Spec.Output.HTTP; srcHTTPOutput != nil { - dst.Spec.Output.HTTP = &LogPipelineHTTPOutput{ - Host: convertValueTypeToAlpha(srcHTTPOutput.Host), - URI: srcHTTPOutput.URI, - Port: srcHTTPOutput.Port, - Compress: srcHTTPOutput.Compress, - Format: srcHTTPOutput.Format, - TLS: convertOutputTLSToAlpha(srcHTTPOutput.TLSConfig), - Dedot: srcHTTPOutput.Dedot, - } - - dst.Spec.Output.HTTP.User = convertValueTypeToAlphaPtr(srcHTTPOutput.User) - dst.Spec.Output.HTTP.Password = convertValueTypeToAlphaPtr(srcHTTPOutput.Password) - } - - if src.Spec.Output.OTLP != nil { - dst.Spec.Output.OTLP = convertOTLPOutputToAlpha(src.Spec.Output.OTLP) - } - - if srcCustomOutput := src.Spec.Output.Custom; srcCustomOutput != "" { - dst.Spec.Output.Custom = srcCustomOutput - } - if src.Spec.Transforms != nil { for _, t := range src.Spec.Transforms { dst.Spec.Transforms = append(dst.Spec.Transforms, convertTransformSpecToAlpha(t)) @@ -202,6 +185,34 @@ func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { return nil } +func convertHTTPOutputToAlpha(output *telemetryv1beta1.LogPipelineHTTPOutput) *LogPipelineHTTPOutput { + if output == nil { + return nil + } + + result := &LogPipelineHTTPOutput{ + Host: convertValueTypeToAlpha(output.Host), + URI: output.URI, + Port: output.Port, + Compress: output.Compress, + Format: output.Format, + TLS: convertOutputTLSToAlpha(output.TLSConfig), + Dedot: output.Dedot, + } + + if output.User != nil && (output.User.Value != "" || output.User.ValueFrom != nil) { + user := convertValueTypeToAlpha(*output.User) + result.User = &user + } + + if output.Password != nil && (output.Password.Value != "" || output.Password.ValueFrom != nil) { + password := convertValueTypeToAlpha(*output.Password) + result.Password = &password + } + + return result +} + func convertRuntimeToAlpha(runtime *telemetryv1beta1.LogPipelineRuntimeInput) *LogPipelineApplicationInput { if runtime == nil { return nil @@ -233,8 +244,8 @@ func convertOutputTLSToAlpha(src telemetryv1beta1.OutputTLS) LogPipelineOutputTL dst.Cert = convertValueTypeToAlphaPtr(src.Cert) dst.Key = convertValueTypeToAlphaPtr(src.Key) - dst.Disabled = src.Disabled - dst.SkipCertificateValidation = src.SkipCertificateValidation + dst.Disabled = src.Insecure + dst.SkipCertificateValidation = src.InsecureSkipVerify return dst } diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion_test.go b/apis/telemetry/v1alpha1/logpipeline_conversion_test.go index b5d08edc69..285baa05f6 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion_test.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion_test.go @@ -79,6 +79,7 @@ var v1alpha1LogPipeline = &LogPipeline{ Compress: "on", Format: "json", TLS: LogPipelineOutputTLS{ + Disabled: true, SkipCertificateValidation: true, CA: &ValueType{ Value: "ca", @@ -221,7 +222,8 @@ var v1beta1LogPipeline = &telemetryv1beta1.LogPipeline{ Compress: "on", Format: "json", TLSConfig: telemetryv1beta1.OutputTLS{ - SkipCertificateValidation: true, + Insecure: true, + InsecureSkipVerify: true, CA: &telemetryv1beta1.ValueType{ Value: "ca", }, @@ -263,11 +265,11 @@ var v1beta1LogPipeline = &telemetryv1beta1.LogPipeline{ }, }, TLS: &telemetryv1beta1.OutputTLS{ - Disabled: true, - SkipCertificateValidation: true, - CA: &telemetryv1beta1.ValueType{Value: "ca"}, - Cert: &telemetryv1beta1.ValueType{Value: "cert"}, - Key: &telemetryv1beta1.ValueType{Value: "key"}, + Insecure: true, + InsecureSkipVerify: true, + CA: &telemetryv1beta1.ValueType{Value: "ca"}, + Cert: &telemetryv1beta1.ValueType{Value: "cert"}, + Key: &telemetryv1beta1.ValueType{Value: "key"}, }, }, }, diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion.go b/apis/telemetry/v1alpha1/metricpipeline_conversion.go index d79ebda3ca..b47c05b55d 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion.go @@ -22,7 +22,7 @@ func (src *MetricPipeline) ConvertTo(dstRaw conversion.Hub) error { // Copy metadata dst.ObjectMeta = src.ObjectMeta - // Copy Spec fields + // Copy input fields dst.Spec.Input = telemetryv1beta1.MetricPipelineInput{} if src.Spec.Input.Prometheus != nil { dst.Spec.Input.Prometheus = &telemetryv1beta1.MetricPipelinePrometheusInput{ @@ -56,11 +56,11 @@ func (src *MetricPipeline) ConvertTo(dstRaw conversion.Hub) error { } } + // Copy output fields dst.Spec.Output = telemetryv1beta1.MetricPipelineOutput{} - if src.Spec.Output.OTLP != nil { - dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) - } + dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) + // Copy everything else if src.Spec.Transforms != nil { for _, t := range src.Spec.Transforms { dst.Spec.Transforms = append(dst.Spec.Transforms, convertTransformSpecToBeta(t)) @@ -88,7 +88,7 @@ func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { // Copy metadata dst.ObjectMeta = src.ObjectMeta - // Copy Spec fields + // Copy input fields dst.Spec.Input = MetricPipelineInput{} if src.Spec.Input.Prometheus != nil { dst.Spec.Input.Prometheus = &MetricPipelinePrometheusInput{ @@ -122,11 +122,13 @@ func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { } } + // Copy output fields dst.Spec.Output = MetricPipelineOutput{} if src.Spec.Output.OTLP != nil { dst.Spec.Output.OTLP = convertOTLPOutputToAlpha(src.Spec.Output.OTLP) } + // Copy everything else if src.Spec.Transforms != nil { for _, t := range src.Spec.Transforms { dst.Spec.Transforms = append(dst.Spec.Transforms, convertTransformSpecToAlpha(t)) diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go b/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go index ad26a505a6..43c4b67e5b 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion_test.go @@ -87,7 +87,7 @@ var v1alpha1MetricPipeline = &MetricPipeline{ Value: "otlp-collector:4317", }, TLS: &OTLPTLS{ - Insecure: false, + Insecure: true, InsecureSkipVerify: true, CA: &ValueType{Value: "ca-cert"}, Cert: &ValueType{Value: "cert"}, @@ -188,11 +188,11 @@ var v1beta1MetricPipeline = &telemetryv1beta1.MetricPipeline{ Value: "otlp-collector:4317", }, TLS: &telemetryv1beta1.OutputTLS{ - Disabled: false, - SkipCertificateValidation: true, - CA: &telemetryv1beta1.ValueType{Value: "ca-cert"}, - Cert: &telemetryv1beta1.ValueType{Value: "cert"}, - Key: &telemetryv1beta1.ValueType{Value: "key"}, + Insecure: true, + InsecureSkipVerify: true, + CA: &telemetryv1beta1.ValueType{Value: "ca-cert"}, + Cert: &telemetryv1beta1.ValueType{Value: "cert"}, + Key: &telemetryv1beta1.ValueType{Value: "key"}, }, Headers: []telemetryv1beta1.Header{ {Name: "header1", ValueType: telemetryv1beta1.ValueType{Value: "value1"}, Prefix: "myPrefix"}, diff --git a/apis/telemetry/v1alpha1/shared_types_conversion.go b/apis/telemetry/v1alpha1/shared_types_conversion.go index 59f995115e..688045906e 100644 --- a/apis/telemetry/v1alpha1/shared_types_conversion.go +++ b/apis/telemetry/v1alpha1/shared_types_conversion.go @@ -3,6 +3,8 @@ package v1alpha1 import ( "regexp" + "k8s.io/utils/ptr" + telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" ) @@ -20,6 +22,28 @@ func sanitizeNamespaceNames(names []string) []string { return valid } +func convertOTLPInputToBeta(src *OTLPInput) *telemetryv1beta1.OTLPInput { + if src == nil { + return nil + } + + return &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(!src.Disabled), + Namespaces: convertNamespaceSelectorToBeta(src.Namespaces), + } +} + +func convertOTLPInputToAlpha(src *telemetryv1beta1.OTLPInput) *OTLPInput { + if src == nil { + return nil + } + + return &OTLPInput{ + Disabled: src.Enabled != nil && !*src.Enabled, + Namespaces: convertNamespaceSelectorToAlpha(src.Namespaces), + } +} + func convertNamespaceSelectorToBeta(ns *NamespaceSelector) *telemetryv1beta1.NamespaceSelector { if ns == nil { return nil @@ -213,11 +237,11 @@ func convertOTLPTLSToBeta(t *OTLPTLS) *telemetryv1beta1.OutputTLS { } return &telemetryv1beta1.OutputTLS{ - Disabled: t.Insecure, - SkipCertificateValidation: t.InsecureSkipVerify, - CA: convertValueTypeToBetaPtr(t.CA), - Cert: convertValueTypeToBetaPtr(t.Cert), - Key: convertValueTypeToBetaPtr(t.Key), + Insecure: t.Insecure, + InsecureSkipVerify: t.InsecureSkipVerify, + CA: convertValueTypeToBetaPtr(t.CA), + Cert: convertValueTypeToBetaPtr(t.Cert), + Key: convertValueTypeToBetaPtr(t.Key), } } @@ -227,8 +251,8 @@ func convertOTLPTLSToAlpha(t *telemetryv1beta1.OutputTLS) *OTLPTLS { } return &OTLPTLS{ - Insecure: t.Disabled, - InsecureSkipVerify: t.SkipCertificateValidation, + Insecure: t.Insecure, + InsecureSkipVerify: t.InsecureSkipVerify, CA: convertValueTypeToAlphaPtr(t.CA), Cert: convertValueTypeToAlphaPtr(t.Cert), Key: convertValueTypeToAlphaPtr(t.Key), diff --git a/apis/telemetry/v1beta1/shared_types.go b/apis/telemetry/v1beta1/shared_types.go index 5d56aab592..975bc3bd72 100644 --- a/apis/telemetry/v1beta1/shared_types.go +++ b/apis/telemetry/v1beta1/shared_types.go @@ -96,12 +96,12 @@ type Header struct { // OutputTLS defines TLS options for an output. // +kubebuilder:validation:XValidation:rule="has(self.cert) == has(self.key)", message="Can define either both 'cert' and 'key', or neither" type OutputTLS struct { - // Disabled specifies if TLS is disabled or enabled. Default is `false`. + // Insecure defines whether to send requests using plaintext instead of TLS. // +kubebuilder:validation:Optional - Disabled bool `json:"disabled,omitempty"` - // If `true`, the validation of certificates is skipped. Default is `false`. + Insecure bool `json:"insecure,omitempty"` + // InsecureSkipVerify defines whether to skip server certificate verification when using TLS. // +kubebuilder:validation:Optional - SkipCertificateValidation bool `json:"skipCertificateValidation,omitempty"` + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` // Defines an optional CA certificate for server certificate verification when using TLS. The certificate must be provided in PEM format. // +kubebuilder:validation:Optional CA *ValueType `json:"ca,omitempty"` diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml index 6a75206276..10b9bb50d0 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml @@ -1552,9 +1552,13 @@ spec: - message: Exactly one of 'value' or 'valueFrom' must be set rule: has(self.value) != has(self.valueFrom) - disabled: - description: Disabled specifies if TLS is disabled or - enabled. Default is `false`. + insecure: + description: Insecure defines whether to send requests + using plaintext instead of TLS. + type: boolean + insecureSkipVerify: + description: InsecureSkipVerify defines whether to skip + server certificate verification when using TLS. type: boolean key: description: Defines the client key to use when using @@ -1601,10 +1605,6 @@ spec: - message: Exactly one of 'value' or 'valueFrom' must be set rule: has(self.value) != has(self.valueFrom) - skipCertificateValidation: - description: If `true`, the validation of certificates - is skipped. Default is `false`. - type: boolean type: object x-kubernetes-validations: - message: Can define either both 'cert' and 'key', or neither @@ -1976,9 +1976,13 @@ spec: - message: Exactly one of 'value' or 'valueFrom' must be set rule: has(self.value) != has(self.valueFrom) - disabled: - description: Disabled specifies if TLS is disabled or - enabled. Default is `false`. + insecure: + description: Insecure defines whether to send requests + using plaintext instead of TLS. + type: boolean + insecureSkipVerify: + description: InsecureSkipVerify defines whether to skip + server certificate verification when using TLS. type: boolean key: description: Defines the client key to use when using @@ -2025,10 +2029,6 @@ spec: - message: Exactly one of 'value' or 'valueFrom' must be set rule: has(self.value) != has(self.valueFrom) - skipCertificateValidation: - description: If `true`, the validation of certificates - is skipped. Default is `false`. - type: boolean type: object x-kubernetes-validations: - message: Can define either both 'cert' and 'key', or neither diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml index 6f9fba2166..0edd2038bd 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml @@ -1432,9 +1432,13 @@ spec: - message: Exactly one of 'value' or 'valueFrom' must be set rule: has(self.value) != has(self.valueFrom) - disabled: - description: Disabled specifies if TLS is disabled or - enabled. Default is `false`. + insecure: + description: Insecure defines whether to send requests + using plaintext instead of TLS. + type: boolean + insecureSkipVerify: + description: InsecureSkipVerify defines whether to skip + server certificate verification when using TLS. type: boolean key: description: Defines the client key to use when using @@ -1481,10 +1485,6 @@ spec: - message: Exactly one of 'value' or 'valueFrom' must be set rule: has(self.value) != has(self.valueFrom) - skipCertificateValidation: - description: If `true`, the validation of certificates - is skipped. Default is `false`. - type: boolean type: object x-kubernetes-validations: - message: Can define either both 'cert' and 'key', or neither diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_tracepipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_tracepipelines.yaml index bbd104f2ad..b73a964820 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_tracepipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_tracepipelines.yaml @@ -940,9 +940,13 @@ spec: - message: Exactly one of 'value' or 'valueFrom' must be set rule: has(self.value) != has(self.valueFrom) - disabled: - description: Disabled specifies if TLS is disabled or - enabled. Default is `false`. + insecure: + description: Insecure defines whether to send requests + using plaintext instead of TLS. + type: boolean + insecureSkipVerify: + description: InsecureSkipVerify defines whether to skip + server certificate verification when using TLS. type: boolean key: description: Defines the client key to use when using @@ -989,10 +993,6 @@ spec: - message: Exactly one of 'value' or 'valueFrom' must be set rule: has(self.value) != has(self.valueFrom) - skipCertificateValidation: - description: If `true`, the validation of certificates - is skipped. Default is `false`. - type: boolean type: object x-kubernetes-validations: - message: Can define either both 'cert' and 'key', or neither diff --git a/internal/webhookcert/webhook_cert_test.go b/internal/webhookcert/webhook_cert_test.go index 97e21fb521..8dbfb8ef51 100644 --- a/internal/webhookcert/webhook_cert_test.go +++ b/internal/webhookcert/webhook_cert_test.go @@ -50,6 +50,21 @@ var ( }, }, } + + metricPipelinesCRD = apiextensionsv1.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: "metricpipelines.telemetry.kyma-project.io", + }, + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Conversion: &apiextensionsv1.CustomResourceConversion{ + Strategy: apiextensionsv1.WebhookConverter, + Webhook: &apiextensionsv1.WebhookConversion{ + ClientConfig: &apiextensionsv1.WebhookClientConfig{}, + }, + }, + }, + } + labels = map[string]string{ "app.kubernetes.io/component": "telemetry", "app.kubernetes.io/instance": "telemetry-manager", @@ -224,51 +239,68 @@ var ( } ) -func TestUpdateLogPipelineWithWebhookConfig(t *testing.T) { - scheme := runtime.NewScheme() - require.NoError(t, clientgoscheme.AddToScheme(scheme)) - require.NoError(t, apiextensionsv1.AddToScheme(scheme)) - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&logPipelinesCRD, &validatingWebhookConfiguration, &mutatingWebhookConfiguration).Build() - - certDir := t.TempDir() - defer func(path string) { - deleteErr := os.RemoveAll(path) - require.NoError(t, deleteErr) - }(certDir) - - config := Config{ - rsaKeySize: testRsaKeySize, - CertDir: certDir, - ServiceName: webhookService, - CASecretName: caBundleSecret, - ValidatingWebhookName: validatingWebhookNamespacedName, - MutatingWebhookName: mutatingWebhookNamespacedName, +func TestUpdatePipelineWithWebhookConfig(t *testing.T) { + tests := []struct { + name string + crd *apiextensionsv1.CustomResourceDefinition + }{ + { + name: "logpipeline", + crd: &logPipelinesCRD, + }, + { + name: "metricpipeline", + crd: &metricPipelinesCRD, + }, } - err := EnsureCertificate(t.Context(), client, config) - require.NoError(t, err) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + scheme := runtime.NewScheme() + require.NoError(t, clientgoscheme.AddToScheme(scheme)) + require.NoError(t, apiextensionsv1.AddToScheme(scheme)) + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&logPipelinesCRD, &metricPipelinesCRD, &validatingWebhookConfiguration, &mutatingWebhookConfiguration).Build() + + certDir := t.TempDir() + defer func(path string) { + deleteErr := os.RemoveAll(path) + require.NoError(t, deleteErr) + }(certDir) + + config := Config{ + rsaKeySize: testRsaKeySize, + CertDir: certDir, + ServiceName: webhookService, + CASecretName: caBundleSecret, + ValidatingWebhookName: validatingWebhookNamespacedName, + MutatingWebhookName: mutatingWebhookNamespacedName, + } - serverCert, err := os.ReadFile(path.Join(certDir, "tls.crt")) - require.NoError(t, err) + err := EnsureCertificate(t.Context(), client, config) + require.NoError(t, err) - var crd apiextensionsv1.CustomResourceDefinition + serverCert, err := os.ReadFile(path.Join(certDir, "tls.crt")) + require.NoError(t, err) - require.NoError(t, client.Get(t.Context(), types.NamespacedName{Name: "logpipelines.telemetry.kyma-project.io"}, &crd)) + var crd apiextensionsv1.CustomResourceDefinition + require.NoError(t, client.Get(t.Context(), types.NamespacedName{Name: tt.crd.Name}, &crd)) - require.Equal(t, apiextensionsv1.WebhookConverter, crd.Spec.Conversion.Strategy) - require.Equal(t, webhookService.Name, crd.Spec.Conversion.Webhook.ClientConfig.Service.Name) - require.Equal(t, webhookService.Namespace, crd.Spec.Conversion.Webhook.ClientConfig.Service.Namespace) - require.Equal(t, int32(443), *crd.Spec.Conversion.Webhook.ClientConfig.Service.Port) - require.Equal(t, "/convert", *crd.Spec.Conversion.Webhook.ClientConfig.Service.Path) + require.Equal(t, apiextensionsv1.WebhookConverter, crd.Spec.Conversion.Strategy) + require.Equal(t, webhookService.Name, crd.Spec.Conversion.Webhook.ClientConfig.Service.Name) + require.Equal(t, webhookService.Namespace, crd.Spec.Conversion.Webhook.ClientConfig.Service.Namespace) + require.Equal(t, int32(443), *crd.Spec.Conversion.Webhook.ClientConfig.Service.Port) + require.Equal(t, "/convert", *crd.Spec.Conversion.Webhook.ClientConfig.Service.Path) - crdCABundle := crd.Spec.Conversion.Webhook.ClientConfig.CABundle - require.NotEmpty(t, crdCABundle) + crdCABundle := crd.Spec.Conversion.Webhook.ClientConfig.CABundle + require.NotEmpty(t, crdCABundle) - var chainChecker certChainCheckerImpl + var chainChecker certChainCheckerImpl - certValid, err := chainChecker.checkRoot(t.Context(), serverCert, crdCABundle) - require.NoError(t, err) - require.True(t, certValid) + certValid, err := chainChecker.checkRoot(t.Context(), serverCert, crdCABundle) + require.NoError(t, err) + require.True(t, certValid) + }) + } } func TestUpdateWebhookConfig(t *testing.T) { @@ -276,7 +308,7 @@ func TestUpdateWebhookConfig(t *testing.T) { require.NoError(t, clientgoscheme.AddToScheme(scheme)) require.NoError(t, apiextensionsv1.AddToScheme(scheme)) - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&logPipelinesCRD, &validatingWebhookConfiguration, &mutatingWebhookConfiguration).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&logPipelinesCRD, &metricPipelinesCRD, &validatingWebhookConfiguration, &mutatingWebhookConfiguration).Build() certDir := t.TempDir() @@ -360,7 +392,7 @@ func TestCreateSecret(t *testing.T) { scheme := runtime.NewScheme() require.NoError(t, clientgoscheme.AddToScheme(scheme)) require.NoError(t, apiextensionsv1.AddToScheme(scheme)) - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&logPipelinesCRD, &validatingWebhookConfiguration, &mutatingWebhookConfiguration).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&logPipelinesCRD, &metricPipelinesCRD, &validatingWebhookConfiguration, &mutatingWebhookConfiguration).Build() certDir := t.TempDir() @@ -394,7 +426,7 @@ func TestReuseExistingCertificate(t *testing.T) { scheme := runtime.NewScheme() require.NoError(t, clientgoscheme.AddToScheme(scheme)) require.NoError(t, apiextensionsv1.AddToScheme(scheme)) - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&logPipelinesCRD, &validatingWebhookConfiguration, &mutatingWebhookConfiguration).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&logPipelinesCRD, &metricPipelinesCRD, &validatingWebhookConfiguration, &mutatingWebhookConfiguration).Build() certDir := t.TempDir() diff --git a/test/e2e/logs/misc/version_conversion_test.go b/test/e2e/logs/misc/version_conversion_test.go index 264f20383a..65d1b2f719 100644 --- a/test/e2e/logs/misc/version_conversion_test.go +++ b/test/e2e/logs/misc/version_conversion_test.go @@ -57,7 +57,7 @@ func TestVersionConversion(t *testing.T) { Port: "443", URI: "/", TLSConfig: telemetryv1beta1.OutputTLS{ - Disabled: true, + Insecure: true, }, }, }, diff --git a/test/e2e/logs/shared/single_pipeline_v1beta1_test.go b/test/e2e/logs/shared/single_pipeline_v1beta1_test.go index 7a46cc8299..ca8fb1ffd4 100644 --- a/test/e2e/logs/shared/single_pipeline_v1beta1_test.go +++ b/test/e2e/logs/shared/single_pipeline_v1beta1_test.go @@ -71,8 +71,8 @@ func TestSinglePipelineV1Beta1_OTel(t *testing.T) { }, Protocol: telemetryv1beta1.OTLPProtocolGRPC, TLS: &telemetryv1beta1.OutputTLS{ - Disabled: true, - SkipCertificateValidation: true, + Insecure: true, + InsecureSkipVerify: true, }, }, }, @@ -130,8 +130,8 @@ func TestSinglePipelineV1Beta1_FluentBit(t *testing.T) { Port: strconv.Itoa(int(backend.Port())), URI: "/", TLSConfig: telemetryv1beta1.OutputTLS{ - Disabled: true, - SkipCertificateValidation: true, + Insecure: true, + InsecureSkipVerify: true, }, }, }, diff --git a/webhook/metricpipeline/v1beta1/defaulter.go b/webhook/metricpipeline/v1beta1/defaulter.go index 08072cc122..64627b603a 100644 --- a/webhook/metricpipeline/v1beta1/defaulter.go +++ b/webhook/metricpipeline/v1beta1/defaulter.go @@ -45,47 +45,47 @@ func (md defaulter) Default(ctx context.Context, obj runtime.Object) error { } func (md defaulter) applyDefaults(pipeline *telemetryv1beta1.MetricPipeline) { - if prometheusInputEnabled(pipeline) && pipeline.Spec.Input.Prometheus.Namespaces == nil { - pipeline.Spec.Input.Prometheus.Namespaces = &telemetryv1beta1.NamespaceSelector{ - Exclude: md.ExcludeNamespaces, + if prometheusInputEnabled(pipeline) { + if pipeline.Spec.Input.Prometheus.Namespaces == nil { + pipeline.Spec.Input.Prometheus.Namespaces = &telemetryv1beta1.NamespaceSelector{ + Exclude: md.ExcludeNamespaces, + } } - } - if istioInputEnabled(pipeline) && pipeline.Spec.Input.Istio.Namespaces == nil { - pipeline.Spec.Input.Istio.Namespaces = &telemetryv1beta1.NamespaceSelector{ - Exclude: md.ExcludeNamespaces, + if pipeline.Spec.Input.Prometheus.DiagnosticMetrics == nil { + pipeline.Spec.Input.Prometheus.DiagnosticMetrics = &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: &md.DiagnosticMetricsEnabled, + } } } - if runtimeInputEnabled(pipeline) && pipeline.Spec.Input.Runtime.Namespaces == nil { - pipeline.Spec.Input.Runtime.Namespaces = &telemetryv1beta1.NamespaceSelector{ - Exclude: md.ExcludeNamespaces, + if istioInputEnabled(pipeline) { + if pipeline.Spec.Input.Istio.Namespaces == nil { + pipeline.Spec.Input.Istio.Namespaces = &telemetryv1beta1.NamespaceSelector{ + Exclude: md.ExcludeNamespaces, + } } - } - - if runtimeInputEnabled(pipeline) { - md.applyRuntimeInputResourceDefaults(pipeline) - } - - if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { - pipeline.Spec.Output.OTLP.Protocol = md.DefaultOTLPOutputProtocol - } - if istioInputEnabled(pipeline) && pipeline.Spec.Input.Istio.EnvoyMetrics == nil { - pipeline.Spec.Input.Istio.EnvoyMetrics = &telemetryv1beta1.EnvoyMetrics{ - Enabled: &md.EnvoyMetricsEnabled, + if pipeline.Spec.Input.Istio.EnvoyMetrics == nil { + pipeline.Spec.Input.Istio.EnvoyMetrics = &telemetryv1beta1.EnvoyMetrics{ + Enabled: &md.EnvoyMetricsEnabled, + } } - } - if istioInputEnabled(pipeline) && pipeline.Spec.Input.Istio.DiagnosticMetrics == nil { - pipeline.Spec.Input.Istio.DiagnosticMetrics = &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ - Enabled: &md.DiagnosticMetricsEnabled, + if pipeline.Spec.Input.Istio.DiagnosticMetrics == nil { + pipeline.Spec.Input.Istio.DiagnosticMetrics = &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: &md.DiagnosticMetricsEnabled, + } } } - if prometheusInputEnabled(pipeline) && pipeline.Spec.Input.Prometheus.DiagnosticMetrics == nil { - pipeline.Spec.Input.Prometheus.DiagnosticMetrics = &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ - Enabled: &md.DiagnosticMetricsEnabled, + if runtimeInputEnabled(pipeline) { + md.applyRuntimeInputResourceDefaults(pipeline) + + if pipeline.Spec.Input.Runtime.Namespaces == nil { + pipeline.Spec.Input.Runtime.Namespaces = &telemetryv1beta1.NamespaceSelector{ + Exclude: md.ExcludeNamespaces, + } } } @@ -96,6 +96,10 @@ func (md defaulter) applyDefaults(pipeline *telemetryv1beta1.MetricPipeline) { if pipeline.Spec.Input.OTLP.Enabled == nil { pipeline.Spec.Input.OTLP.Enabled = &md.OTLPInputEnabled } + + if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { + pipeline.Spec.Output.OTLP.Protocol = md.DefaultOTLPOutputProtocol + } } func (md defaulter) applyRuntimeInputResourceDefaults(pipeline *telemetryv1beta1.MetricPipeline) { From d842abcae620ad1f7942e0b7fb248ff2a7133b7b Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 16:06:39 +0200 Subject: [PATCH 06/27] fix --- apis/telemetry/v1alpha1/logpipeline_conversion.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index dfc74946d8..ba644780c5 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -31,7 +31,6 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { // Copy Output fields dst.Spec.Output = telemetryv1beta1.LogPipelineOutput{} dst.Spec.Output.HTTP = convertHTTPOutputToBeta(src.Spec.Output.HTTP) - dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) if src.Spec.Output.Custom != "" { dst.Spec.Output.Custom = src.Spec.Output.Custom @@ -154,7 +153,6 @@ func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { dst.Spec.Output = LogPipelineOutput{} dst.Spec.Output.HTTP = convertHTTPOutputToAlpha(src.Spec.Output.HTTP) dst.Spec.Output.OTLP = convertOTLPOutputToAlpha(src.Spec.Output.OTLP) - if src.Spec.Output.Custom != "" { dst.Spec.Output.Custom = src.Spec.Output.Custom } From 9d1e9dc85bff04e872f1ba7dd6feeb175c48df54 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 16:09:16 +0200 Subject: [PATCH 07/27] deleted leftover namespaceSelector --- apis/telemetry/v1beta1/logpipeline_types.go | 14 ----------- .../v1beta1/zz_generated.deepcopy.go | 25 ------------------- 2 files changed, 39 deletions(-) diff --git a/apis/telemetry/v1beta1/logpipeline_types.go b/apis/telemetry/v1beta1/logpipeline_types.go index 90cc8a0c54..4921e1ee17 100644 --- a/apis/telemetry/v1beta1/logpipeline_types.go +++ b/apis/telemetry/v1beta1/logpipeline_types.go @@ -130,20 +130,6 @@ type LogPipelineRuntimeInput struct { KeepOriginalBody *bool `json:"keepOriginalBody,omitempty"` } -// LogPipelineNamespaceSelector describes whether application logs from specific Namespaces are selected. The options are mutually exclusive. System Namespaces are excluded by default. Use the `system` attribute with value `true` to enable them. -// +kubebuilder:validation:XValidation:rule="(has(self.include) == true ? 1 : 0) + (has(self.exclude) == true ? 1 : 0) + (has(self.system) == true ? 1 : 0) <= 1",message="Only one of 'include', 'exclude' or 'system' can be defined" -type LogPipelineNamespaceSelector struct { - // Include only the container logs of the specified Namespace names. - // +kubebuilder:validation:Optional - Include []string `json:"include,omitempty"` - // Exclude the container logs of the specified Namespace names. - // +kubebuilder:validation:Optional - Exclude []string `json:"exclude,omitempty"` - // System specifies whether to collect logs from system namespaces. If set to `true`, you collect logs from all namespaces including system namespaces, such as like kube-system, istio-system, and kyma-system. The default is `false`. - // +kubebuilder:validation:Optional - System bool `json:"system,omitempty"` -} - // LogPipelineContainerSelector describes whether application logs from specific containers are selected. The options are mutually exclusive. // +kubebuilder:validation:XValidation:rule="(has(self.include) == true ? 1 : 0) + (has(self.exclude) == true ? 1 : 0) <= 1",message="Only one of 'include' or 'exclude' can be defined" type LogPipelineContainerSelector struct { diff --git a/apis/telemetry/v1beta1/zz_generated.deepcopy.go b/apis/telemetry/v1beta1/zz_generated.deepcopy.go index 29eb9888c8..23b4c83140 100644 --- a/apis/telemetry/v1beta1/zz_generated.deepcopy.go +++ b/apis/telemetry/v1beta1/zz_generated.deepcopy.go @@ -284,31 +284,6 @@ func (in *LogPipelineList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LogPipelineNamespaceSelector) DeepCopyInto(out *LogPipelineNamespaceSelector) { - *out = *in - if in.Include != nil { - in, out := &in.Include, &out.Include - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Exclude != nil { - in, out := &in.Exclude, &out.Exclude - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LogPipelineNamespaceSelector. -func (in *LogPipelineNamespaceSelector) DeepCopy() *LogPipelineNamespaceSelector { - if in == nil { - return nil - } - out := new(LogPipelineNamespaceSelector) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LogPipelineOutput) DeepCopyInto(out *LogPipelineOutput) { *out = *in From 4581a1df583730615f3f3f7a39489fd53db8acc4 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 17:00:12 +0200 Subject: [PATCH 08/27] fix --- apis/telemetry/v1beta1/shared_types.go | 2 +- .../templates/telemetry.kyma-project.io_logpipelines.yaml | 2 +- .../templates/telemetry.kyma-project.io_metricpipelines.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apis/telemetry/v1beta1/shared_types.go b/apis/telemetry/v1beta1/shared_types.go index 975bc3bd72..040aed0751 100644 --- a/apis/telemetry/v1beta1/shared_types.go +++ b/apis/telemetry/v1beta1/shared_types.go @@ -117,7 +117,7 @@ type OutputTLS struct { type OTLPInput struct { // If set to `false`, no push-based OTLP signals are collected. The default is `true`. // +kubebuilder:validation:Optional - Enabled *bool `json:"disabled,omitempty"` + Enabled *bool `json:"enabled,omitempty"` // Namespaces describes whether push-based OTLP signals from specific namespaces are selected. System namespaces are enabled by default. // +kubebuilder:validation:Optional Namespaces *NamespaceSelector `json:"namespaces,omitempty"` diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml index 10b9bb50d0..2d9ad56859 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml @@ -1236,7 +1236,7 @@ spec: description: OTLP input configures the push endpoint to receive logs from a OTLP source. properties: - disabled: + enabled: description: If set to `false`, no push-based OTLP signals are collected. The default is `true`. type: boolean diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml index 0edd2038bd..cb172fa687 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml @@ -926,7 +926,7 @@ spec: description: OTLP input configures the push endpoint to receive metrics from an OTLP source. properties: - disabled: + enabled: description: If set to `false`, no push-based OTLP signals are collected. The default is `true`. type: boolean From 4ddd3cd67e5504da8ee44aae180e343265a0dab6 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 17:21:01 +0200 Subject: [PATCH 09/27] refactor --- webhook/metricpipeline/v1alpha1/defaulter.go | 59 +++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/webhook/metricpipeline/v1alpha1/defaulter.go b/webhook/metricpipeline/v1alpha1/defaulter.go index 1bb6308216..3a7400a1e6 100644 --- a/webhook/metricpipeline/v1alpha1/defaulter.go +++ b/webhook/metricpipeline/v1alpha1/defaulter.go @@ -45,49 +45,54 @@ func (md defaulter) Default(ctx context.Context, obj runtime.Object) error { } func (md defaulter) applyDefaults(pipeline *telemetryv1alpha1.MetricPipeline) { - if metricpipelineutils.IsPrometheusInputEnabled(pipeline.Spec.Input) && pipeline.Spec.Input.Prometheus.Namespaces == nil { - pipeline.Spec.Input.Prometheus.Namespaces = &telemetryv1alpha1.NamespaceSelector{ - Exclude: md.ExcludeNamespaces, + if metricpipelineutils.IsPrometheusInputEnabled(pipeline.Spec.Input) { + if pipeline.Spec.Input.Prometheus.Namespaces == nil { + pipeline.Spec.Input.Prometheus.Namespaces = &telemetryv1alpha1.NamespaceSelector{ + Exclude: md.ExcludeNamespaces, + } } - } - if metricpipelineutils.IsIstioInputEnabled(pipeline.Spec.Input) && pipeline.Spec.Input.Istio.Namespaces == nil { - pipeline.Spec.Input.Istio.Namespaces = &telemetryv1alpha1.NamespaceSelector{ - Exclude: md.ExcludeNamespaces, + if pipeline.Spec.Input.Prometheus.DiagnosticMetrics == nil { + pipeline.Spec.Input.Prometheus.DiagnosticMetrics = &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: &md.DiagnosticMetricsEnabled, + } } } - if metricpipelineutils.IsRuntimeInputEnabled(pipeline.Spec.Input) && pipeline.Spec.Input.Runtime.Namespaces == nil { - pipeline.Spec.Input.Runtime.Namespaces = &telemetryv1alpha1.NamespaceSelector{ - Exclude: md.ExcludeNamespaces, + if metricpipelineutils.IsIstioInputEnabled(pipeline.Spec.Input) { + if pipeline.Spec.Input.Istio.Namespaces == nil { + pipeline.Spec.Input.Istio.Namespaces = &telemetryv1alpha1.NamespaceSelector{ + Exclude: md.ExcludeNamespaces, + } + } + + if pipeline.Spec.Input.Istio.DiagnosticMetrics == nil { + pipeline.Spec.Input.Istio.DiagnosticMetrics = &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{ + Enabled: &md.DiagnosticMetricsEnabled, + } + } + + if pipeline.Spec.Input.Istio.EnvoyMetrics == nil { + pipeline.Spec.Input.Istio.EnvoyMetrics = &telemetryv1alpha1.EnvoyMetrics{ + Enabled: &md.EnvoyMetricsEnabled, + } } } if metricpipelineutils.IsRuntimeInputEnabled(pipeline.Spec.Input) { md.applyRuntimeInputResourceDefaults(pipeline) - } - if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { - pipeline.Spec.Output.OTLP.Protocol = md.DefaultOTLPOutputProtocol - } - - if metricpipelineutils.IsIstioInputEnabled(pipeline.Spec.Input) && pipeline.Spec.Input.Istio.DiagnosticMetrics == nil { - pipeline.Spec.Input.Istio.DiagnosticMetrics = &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{ - Enabled: &md.DiagnosticMetricsEnabled, + if pipeline.Spec.Input.Runtime.Namespaces == nil { + pipeline.Spec.Input.Runtime.Namespaces = &telemetryv1alpha1.NamespaceSelector{ + Exclude: md.ExcludeNamespaces, + } } } - if metricpipelineutils.IsIstioInputEnabled(pipeline.Spec.Input) && pipeline.Spec.Input.Istio.EnvoyMetrics == nil { - pipeline.Spec.Input.Istio.EnvoyMetrics = &telemetryv1alpha1.EnvoyMetrics{ - Enabled: &md.EnvoyMetricsEnabled, - } + if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { + pipeline.Spec.Output.OTLP.Protocol = md.DefaultOTLPOutputProtocol } - if metricpipelineutils.IsPrometheusInputEnabled(pipeline.Spec.Input) && pipeline.Spec.Input.Prometheus.DiagnosticMetrics == nil { - pipeline.Spec.Input.Prometheus.DiagnosticMetrics = &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{ - Enabled: &md.DiagnosticMetricsEnabled, - } - } } func (md defaulter) applyRuntimeInputResourceDefaults(pipeline *telemetryv1alpha1.MetricPipeline) { From 13ad47f17268f0bf06cae5a74571483a55bc965d Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 17:27:56 +0200 Subject: [PATCH 10/27] fix --- apis/telemetry/v1alpha1/metricpipeline_conversion.go | 2 +- apis/telemetry/v1alpha1/shared_types_conversion.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion.go b/apis/telemetry/v1alpha1/metricpipeline_conversion.go index b47c05b55d..bc7931895f 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion.go @@ -117,7 +117,7 @@ func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { if src.Spec.Input.OTLP != nil { dst.Spec.Input.OTLP = &OTLPInput{ - Disabled: src.Spec.Input.OTLP.Enabled != nil && !*src.Spec.Input.OTLP.Enabled, + Disabled: src.Spec.Input.OTLP.Enabled != nil && ptr.Deref(src.Spec.Input.OTLP.Enabled, false), Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.OTLP.Namespaces), } } diff --git a/apis/telemetry/v1alpha1/shared_types_conversion.go b/apis/telemetry/v1alpha1/shared_types_conversion.go index 688045906e..d628326711 100644 --- a/apis/telemetry/v1alpha1/shared_types_conversion.go +++ b/apis/telemetry/v1alpha1/shared_types_conversion.go @@ -39,7 +39,7 @@ func convertOTLPInputToAlpha(src *telemetryv1beta1.OTLPInput) *OTLPInput { } return &OTLPInput{ - Disabled: src.Enabled != nil && !*src.Enabled, + Disabled: src.Enabled != nil && ptr.Deref(src.Enabled, false), Namespaces: convertNamespaceSelectorToAlpha(src.Namespaces), } } From 0be3020587e35d5cbf1328db38e85c10774c35e4 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 17:48:15 +0200 Subject: [PATCH 11/27] fix --- .../v1alpha1/metricpipeline_conversion.go | 16 ++-------------- .../v1alpha1/shared_types_conversion.go | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion.go b/apis/telemetry/v1alpha1/metricpipeline_conversion.go index bc7931895f..6eba80110d 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion.go @@ -3,7 +3,6 @@ package v1alpha1 import ( "errors" - "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/conversion" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" @@ -49,12 +48,7 @@ func (src *MetricPipeline) ConvertTo(dstRaw conversion.Hub) error { } } - if src.Spec.Input.OTLP != nil { - dst.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(!src.Spec.Input.OTLP.Disabled), - Namespaces: convertNamespaceSelectorToBeta(src.Spec.Input.OTLP.Namespaces), - } - } + dst.Spec.Input.OTLP = convertOTLPInputToBeta(src.Spec.Input.OTLP) // Copy output fields dst.Spec.Output = telemetryv1beta1.MetricPipelineOutput{} @@ -114,13 +108,7 @@ func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { EnvoyMetrics: convertEnvoyMetricsToAlpha(src.Spec.Input.Istio.EnvoyMetrics), } } - - if src.Spec.Input.OTLP != nil { - dst.Spec.Input.OTLP = &OTLPInput{ - Disabled: src.Spec.Input.OTLP.Enabled != nil && ptr.Deref(src.Spec.Input.OTLP.Enabled, false), - Namespaces: convertNamespaceSelectorToAlpha(src.Spec.Input.OTLP.Namespaces), - } - } + dst.Spec.Input.OTLP = convertOTLPInputToAlpha(src.Spec.Input.OTLP) // Copy output fields dst.Spec.Output = MetricPipelineOutput{} diff --git a/apis/telemetry/v1alpha1/shared_types_conversion.go b/apis/telemetry/v1alpha1/shared_types_conversion.go index d628326711..c1bdb3d490 100644 --- a/apis/telemetry/v1alpha1/shared_types_conversion.go +++ b/apis/telemetry/v1alpha1/shared_types_conversion.go @@ -39,7 +39,7 @@ func convertOTLPInputToAlpha(src *telemetryv1beta1.OTLPInput) *OTLPInput { } return &OTLPInput{ - Disabled: src.Enabled != nil && ptr.Deref(src.Enabled, false), + Disabled: src.Enabled != nil && !ptr.Deref(src.Enabled, false), Namespaces: convertNamespaceSelectorToAlpha(src.Namespaces), } } From d1ce8a97990f1adaa6b4523659fec9dbf3925df1 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 20 Oct 2025 18:00:18 +0200 Subject: [PATCH 12/27] fix --- .testcoverage.yml | 2 +- apis/telemetry/v1alpha1/logpipeline_conversion.go | 2 ++ apis/telemetry/v1alpha1/metricpipeline_conversion.go | 1 + webhook/metricpipeline/v1alpha1/defaulter.go | 1 - 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.testcoverage.yml b/.testcoverage.yml index dafbe05e93..3a6955a1ce 100644 --- a/.testcoverage.yml +++ b/.testcoverage.yml @@ -47,7 +47,7 @@ override: path: ^internal/validators/secretref$ - threshold: 75 path: ^internal/resourcelock$ - - threshold: 84 + - threshold: 83 path: ^internal/webhookcert$ - threshold: 74 path: ^webhook/logpipeline/v1alpha1$ diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index ba644780c5..fd2289ca14 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -31,6 +31,7 @@ func (lp *LogPipeline) ConvertTo(dstRaw conversion.Hub) error { // Copy Output fields dst.Spec.Output = telemetryv1beta1.LogPipelineOutput{} dst.Spec.Output.HTTP = convertHTTPOutputToBeta(src.Spec.Output.HTTP) + dst.Spec.Output.OTLP = convertOTLPOutputToBeta(src.Spec.Output.OTLP) if src.Spec.Output.Custom != "" { dst.Spec.Output.Custom = src.Spec.Output.Custom @@ -152,6 +153,7 @@ func (lp *LogPipeline) ConvertFrom(srcRaw conversion.Hub) error { // Copy output fields dst.Spec.Output = LogPipelineOutput{} dst.Spec.Output.HTTP = convertHTTPOutputToAlpha(src.Spec.Output.HTTP) + dst.Spec.Output.OTLP = convertOTLPOutputToAlpha(src.Spec.Output.OTLP) if src.Spec.Output.Custom != "" { dst.Spec.Output.Custom = src.Spec.Output.Custom diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion.go b/apis/telemetry/v1alpha1/metricpipeline_conversion.go index 6eba80110d..98d928291e 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion.go @@ -108,6 +108,7 @@ func (dst *MetricPipeline) ConvertFrom(srcRaw conversion.Hub) error { EnvoyMetrics: convertEnvoyMetricsToAlpha(src.Spec.Input.Istio.EnvoyMetrics), } } + dst.Spec.Input.OTLP = convertOTLPInputToAlpha(src.Spec.Input.OTLP) // Copy output fields diff --git a/webhook/metricpipeline/v1alpha1/defaulter.go b/webhook/metricpipeline/v1alpha1/defaulter.go index 3a7400a1e6..84efa9995a 100644 --- a/webhook/metricpipeline/v1alpha1/defaulter.go +++ b/webhook/metricpipeline/v1alpha1/defaulter.go @@ -92,7 +92,6 @@ func (md defaulter) applyDefaults(pipeline *telemetryv1alpha1.MetricPipeline) { if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { pipeline.Spec.Output.OTLP.Protocol = md.DefaultOTLPOutputProtocol } - } func (md defaulter) applyRuntimeInputResourceDefaults(pipeline *telemetryv1alpha1.MetricPipeline) { From e8c2e1187974313e3a38b1a4d67636209ea6ca00 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Tue, 21 Oct 2025 10:36:38 +0200 Subject: [PATCH 13/27] fix after merge --- apis/telemetry/v1beta1/shared_types.go | 2 +- ...elemetry.kyma-project.io_logpipelines.yaml | 45 ++++++------------- ...metry.kyma-project.io_metricpipelines.yaml | 12 ++--- 3 files changed, 18 insertions(+), 41 deletions(-) diff --git a/apis/telemetry/v1beta1/shared_types.go b/apis/telemetry/v1beta1/shared_types.go index bab241ca81..9f82d83293 100644 --- a/apis/telemetry/v1beta1/shared_types.go +++ b/apis/telemetry/v1beta1/shared_types.go @@ -115,7 +115,7 @@ type OutputTLS struct { // OTLPInput defines the collection of push-based metrics that use the OpenTelemetry protocol. type OTLPInput struct { - // ENabled specifies if the 'otlp' input is enabled. If enabled, then push-based OTLP signals are collected. The default is `true`. + // Enabled specifies if the 'otlp' input is enabled. If enabled, then push-based OTLP signals are collected. The default is `true`. // +kubebuilder:validation:Optional Enabled *bool `json:"enabled,omitempty"` // Namespaces describes whether push-based OTLP signals from specific namespaces are selected. System namespaces are enabled by default. diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml index 4f9c68cb05..ef3e76780a 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml @@ -1255,16 +1255,10 @@ spec: description: OTLP input configures the push endpoint to receive logs from a OTLP source. properties: -<<<<<<< HEAD enabled: - description: If set to `false`, no push-based OTLP signals - are collected. The default is `true`. -======= - disabled: - description: Disabled specifies if the 'otlp' input is deactivated. - If disabled, then no push-based OTLP signals are collected. - The default is `false`. ->>>>>>> main + description: Enabled specifies if the 'otlp' input is enabled. + If enabled, then push-based OTLP signals are collected. + The default is `true`. type: boolean namespaces: description: Namespaces describes whether push-based OTLP @@ -1355,32 +1349,22 @@ spec: system namespaces, use an empty struct notation. properties: exclude: -<<<<<<< HEAD - description: Exclude signals from the specified Namespace - names only. -======= - description: Exclude specifies the list of namespace names - to exclude when collecting container logs. By default, - logs from all namespaces are collected, except system - namespaces. You cannot specify an exclude list together - with an include list. ->>>>>>> main + description: 'Exclude telemetry data from the specified + namespace names only. By default, all namespaces (depending + on input type: except system namespaces) are collected. + You cannot specify an exclude list together with an + include list.' items: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string type: array include: -<<<<<<< HEAD - description: Include signals from the specified Namespace - names only. -======= - description: Include specifies the list of namespace names - to include when collecting container logs. By default, - logs from all namespaces are collected, except system - namespaces. You cannot specify an include list together - with an exclude list. ->>>>>>> main + description: 'Include telemetry data from the specified + namespace names only. By default, all namespaces (depending + on input type: except system namespaces) are included. + You cannot specify an include list together with an + exclude list.' items: maxLength: 63 pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ @@ -1389,8 +1373,7 @@ spec: type: object x-kubernetes-validations: - message: Only one of 'include' or 'exclude' can be defined - rule: '(has(self.include) == true ? 1 : 0) + (has(self.exclude) - == true ? 1 : 0) <= 1' + rule: '!(has(self.include) && has(self.exclude))' type: object type: object output: diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml index c3dead623c..157a84969b 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml @@ -973,16 +973,10 @@ spec: description: OTLP input configures the push endpoint to receive metrics from an OTLP source. properties: -<<<<<<< HEAD enabled: - description: If set to `false`, no push-based OTLP signals - are collected. The default is `true`. -======= - disabled: - description: Disabled specifies if the 'otlp' input is deactivated. - If disabled, then no push-based OTLP signals are collected. - The default is `false`. ->>>>>>> main + description: Enabled specifies if the 'otlp' input is enabled. + If enabled, then push-based OTLP signals are collected. + The default is `true`. type: boolean namespaces: description: Namespaces describes whether push-based OTLP From bfd05be1968d8520fe412843c50a2b57323364d5 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Tue, 21 Oct 2025 10:42:11 +0200 Subject: [PATCH 14/27] fix --- webhook/logpipeline/v1beta1/defaulter.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/webhook/logpipeline/v1beta1/defaulter.go b/webhook/logpipeline/v1beta1/defaulter.go index 8bbe228e8c..8f8bc91d71 100644 --- a/webhook/logpipeline/v1beta1/defaulter.go +++ b/webhook/logpipeline/v1beta1/defaulter.go @@ -53,11 +53,17 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1beta1.LogPipeline) { pipeline.Spec.Output.OTLP.Protocol = ld.DefaultOTLPOutputProtocol } - if pipeline.Spec.Input.OTLP == nil { - pipeline.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{} - } + if isOTLPPipeline(pipeline) { + if pipeline.Spec.Input.OTLP == nil { + pipeline.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{} + } - if pipeline.Spec.Input.OTLP.Enabled == nil { - pipeline.Spec.Input.OTLP.Enabled = &ld.OTLPInputEnabled + if pipeline.Spec.Input.OTLP.Enabled == nil { + pipeline.Spec.Input.OTLP.Enabled = &ld.OTLPInputEnabled + } } } + +func isOTLPPipeline(pipeline *telemetryv1beta1.LogPipeline) bool { + return pipeline.Spec.Output.OTLP != nil +} From 513064c7aeb48babf700ff9e23675073d0caf647 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Tue, 21 Oct 2025 11:03:04 +0200 Subject: [PATCH 15/27] fix --- webhook/logpipeline/v1beta1/defaulter_test.go | 96 ++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/webhook/logpipeline/v1beta1/defaulter_test.go b/webhook/logpipeline/v1beta1/defaulter_test.go index 7acc05c981..731fda93c8 100644 --- a/webhook/logpipeline/v1beta1/defaulter_test.go +++ b/webhook/logpipeline/v1beta1/defaulter_test.go @@ -30,6 +30,13 @@ func TestDefault(t *testing.T) { Input: telemetryv1beta1.LogPipelineInput{ Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{}, }, + Output: telemetryv1beta1.LogPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "localhost:4317", + }, + }, + }, }, }, expected: &telemetryv1beta1.LogPipeline{ @@ -46,6 +53,14 @@ func TestDefault(t *testing.T) { }, }, }, + Output: telemetryv1beta1.LogPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "localhost:4317", + }, + Protocol: telemetryv1beta1.OTLPProtocolGRPC, + }, + }, }, }, }, @@ -58,6 +73,14 @@ func TestDefault(t *testing.T) { KeepOriginalBody: ptr.To(false), }, }, + Output: telemetryv1beta1.LogPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "localhost:4317", + }, + Protocol: telemetryv1beta1.OTLPProtocolGRPC, + }, + }, }, }, expected: &telemetryv1beta1.LogPipeline{ @@ -74,6 +97,14 @@ func TestDefault(t *testing.T) { }, }, }, + Output: telemetryv1beta1.LogPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "localhost:4317", + }, + Protocol: telemetryv1beta1.OTLPProtocolGRPC, + }, + }, }, }, }, @@ -86,6 +117,14 @@ func TestDefault(t *testing.T) { Enabled: ptr.To(false), }, }, + Output: telemetryv1beta1.LogPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "localhost:4317", + }, + Protocol: telemetryv1beta1.OTLPProtocolGRPC, + }, + }, }, }, expected: &telemetryv1beta1.LogPipeline{ @@ -98,6 +137,14 @@ func TestDefault(t *testing.T) { Enabled: ptr.To(false), }, }, + Output: telemetryv1beta1.LogPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "localhost:4317", + }, + Protocol: telemetryv1beta1.OTLPProtocolGRPC, + }, + }, }, }, }, @@ -126,8 +173,19 @@ func TestDefault(t *testing.T) { }, }, { - name: "should enable otlp input by default", - input: &telemetryv1beta1.LogPipeline{}, + name: "should enable otlp input by default for OTLP output pipelines", + input: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Output: telemetryv1beta1.LogPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "localhost:4317", + }, + Protocol: telemetryv1beta1.OTLPProtocolGRPC, + }, + }, + }, + }, expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ @@ -135,6 +193,40 @@ func TestDefault(t *testing.T) { Enabled: ptr.To(true), }, }, + Output: telemetryv1beta1.LogPipelineOutput{ + OTLP: &telemetryv1beta1.OTLPOutput{ + Endpoint: telemetryv1beta1.ValueType{ + Value: "localhost:4317", + }, + Protocol: telemetryv1beta1.OTLPProtocolGRPC, + }, + }, + }, + }, + }, + { + name: "should not activate otlp input by default for non-OTLP output pipelines", + input: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Output: telemetryv1beta1.LogPipelineOutput{ + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ + Value: "localhost", + }, + }, + }, + }, + }, + expected: &telemetryv1beta1.LogPipeline{ + Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{}, + Output: telemetryv1beta1.LogPipelineOutput{ + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ + Value: "localhost", + }, + }, + }, }, }, }, From fa18aa61babccf0466823618481adc2dfe8cdbc6 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Tue, 21 Oct 2025 18:26:50 +0200 Subject: [PATCH 16/27] consistent namespace selector for otlp input --- .../shared/single_pipeline_v1beta1_test.go | 2 +- webhook/logpipeline/v1alpha1/defaulter.go | 14 +++ .../logpipeline/v1alpha1/defaulter_test.go | 86 +++++++++++++++++++ webhook/logpipeline/v1beta1/defaulter.go | 11 ++- webhook/logpipeline/v1beta1/defaulter_test.go | 55 ++++++------ webhook/metricpipeline/v1alpha1/defaulter.go | 8 ++ .../metricpipeline/v1alpha1/defaulter_test.go | 86 ++++++++++++++++++- webhook/metricpipeline/v1beta1/defaulter.go | 7 ++ .../metricpipeline/v1beta1/defaulter_test.go | 65 +++++++++++--- 9 files changed, 290 insertions(+), 44 deletions(-) diff --git a/test/e2e/logs/shared/single_pipeline_v1beta1_test.go b/test/e2e/logs/shared/single_pipeline_v1beta1_test.go index ca8fb1ffd4..71a474523d 100644 --- a/test/e2e/logs/shared/single_pipeline_v1beta1_test.go +++ b/test/e2e/logs/shared/single_pipeline_v1beta1_test.go @@ -92,6 +92,7 @@ func TestSinglePipelineV1Beta1_OTel(t *testing.T) { }) Expect(kitk8s.CreateObjects(t, resources...)).To(Succeed()) + assert.OTelLogPipelineHealthy(t, pipelineName) assert.BackendReachable(t, backend) assert.DeploymentReady(t, kitkyma.LogGatewayName) @@ -99,7 +100,6 @@ func TestSinglePipelineV1Beta1_OTel(t *testing.T) { assert.DaemonSetReady(t, kitkyma.LogAgentName) } - assert.OTelLogPipelineHealthy(t, pipelineName) assert.OTelLogsFromNamespaceDelivered(t, backend, genNs) }) } diff --git a/webhook/logpipeline/v1alpha1/defaulter.go b/webhook/logpipeline/v1alpha1/defaulter.go index a285d57700..adf5d2eb69 100644 --- a/webhook/logpipeline/v1alpha1/defaulter.go +++ b/webhook/logpipeline/v1alpha1/defaulter.go @@ -46,7 +46,21 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1alpha1.LogPipeline) { pipeline.Spec.Input.Application.KeepOriginalBody = &ld.ApplicationInputKeepOriginalBody } + if isOTLPPipelineAlpha(pipeline) { + if pipeline.Spec.Input.OTLP == nil { + pipeline.Spec.Input.OTLP = &telemetryv1alpha1.OTLPInput{} + } + + if pipeline.Spec.Input.OTLP.Namespaces == nil { + pipeline.Spec.Input.OTLP.Namespaces = &telemetryv1alpha1.NamespaceSelector{} + } + } + if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { pipeline.Spec.Output.OTLP.Protocol = ld.DefaultOTLPProtocol } } + +func isOTLPPipelineAlpha(pipeline *telemetryv1alpha1.LogPipeline) bool { + return pipeline.Spec.Output.OTLP != nil +} diff --git a/webhook/logpipeline/v1alpha1/defaulter_test.go b/webhook/logpipeline/v1alpha1/defaulter_test.go index a1fc277743..e149911b2d 100644 --- a/webhook/logpipeline/v1alpha1/defaulter_test.go +++ b/webhook/logpipeline/v1alpha1/defaulter_test.go @@ -26,6 +26,11 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.LogPipeline{ Spec: telemetryv1alpha1.LogPipelineSpec{ Input: telemetryv1alpha1.LogPipelineInput{}, + Output: telemetryv1alpha1.LogPipelineOutput{ + HTTP: &telemetryv1alpha1.LogPipelineHTTPOutput{ + Host: telemetryv1alpha1.ValueType{Value: "example.com"}, + }, + }, }, }, expected: &telemetryv1alpha1.LogPipeline{ @@ -36,6 +41,11 @@ func TestDefault(t *testing.T) { KeepOriginalBody: ptr.To(true), }, }, + Output: telemetryv1alpha1.LogPipelineOutput{ + HTTP: &telemetryv1alpha1.LogPipelineHTTPOutput{ + Host: telemetryv1alpha1.ValueType{Value: "example.com"}, + }, + }, }, }, }, @@ -83,6 +93,79 @@ func TestDefault(t *testing.T) { }, }, }, + { + name: "should set empty namespaces for OTLP input if not set", + input: &telemetryv1alpha1.LogPipeline{ + Spec: telemetryv1alpha1.LogPipelineSpec{ + Input: telemetryv1alpha1.LogPipelineInput{}, + Output: telemetryv1alpha1.LogPipelineOutput{ + OTLP: &telemetryv1alpha1.OTLPOutput{ + Endpoint: telemetryv1alpha1.ValueType{Value: "otlp.example.com:4317"}, + }, + }, + }, + }, + expected: &telemetryv1alpha1.LogPipeline{ + Spec: telemetryv1alpha1.LogPipelineSpec{ + Input: telemetryv1alpha1.LogPipelineInput{ + Application: &telemetryv1alpha1.LogPipelineApplicationInput{ + Enabled: ptr.To(true), + KeepOriginalBody: ptr.To(true), + }, + OTLP: &telemetryv1alpha1.OTLPInput{ + Disabled: false, + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, + }, + Output: telemetryv1alpha1.LogPipelineOutput{ + OTLP: &telemetryv1alpha1.OTLPOutput{ + Endpoint: telemetryv1alpha1.ValueType{Value: "otlp.example.com:4317"}, + Protocol: "grpc", + }, + }, + }, + }, + }, + { + name: "should not set empty namespaces for OTLP input if set", + input: &telemetryv1alpha1.LogPipeline{ + Spec: telemetryv1alpha1.LogPipelineSpec{ + Input: telemetryv1alpha1.LogPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{ + Include: []string{"custom-namespace"}, + }, + }, + }, + Output: telemetryv1alpha1.LogPipelineOutput{ + OTLP: &telemetryv1alpha1.OTLPOutput{ + Endpoint: telemetryv1alpha1.ValueType{Value: "otlp.example.com:4317"}, + }, + }, + }, + }, + expected: &telemetryv1alpha1.LogPipeline{ + Spec: telemetryv1alpha1.LogPipelineSpec{ + Input: telemetryv1alpha1.LogPipelineInput{ + Application: &telemetryv1alpha1.LogPipelineApplicationInput{ + Enabled: ptr.To(true), + KeepOriginalBody: ptr.To(true), + }, + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{ + Include: []string{"custom-namespace"}, + }, + }, + }, + Output: telemetryv1alpha1.LogPipelineOutput{ + OTLP: &telemetryv1alpha1.OTLPOutput{ + Endpoint: telemetryv1alpha1.ValueType{Value: "otlp.example.com:4317"}, + Protocol: "grpc", + }, + }, + }, + }, + }, { name: "should set default OTLP protocol if not set", input: &telemetryv1alpha1.LogPipeline{ @@ -99,6 +182,9 @@ func TestDefault(t *testing.T) { Enabled: ptr.To(true), KeepOriginalBody: ptr.To(true), }, + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, }, Output: telemetryv1alpha1.LogPipelineOutput{ OTLP: &telemetryv1alpha1.OTLPOutput{ diff --git a/webhook/logpipeline/v1beta1/defaulter.go b/webhook/logpipeline/v1beta1/defaulter.go index 8f8bc91d71..b6a75087f6 100644 --- a/webhook/logpipeline/v1beta1/defaulter.go +++ b/webhook/logpipeline/v1beta1/defaulter.go @@ -5,6 +5,7 @@ import ( "fmt" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/webhook" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" @@ -53,7 +54,7 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1beta1.LogPipeline) { pipeline.Spec.Output.OTLP.Protocol = ld.DefaultOTLPOutputProtocol } - if isOTLPPipeline(pipeline) { + if isOTLPPipelineBeta(pipeline) { if pipeline.Spec.Input.OTLP == nil { pipeline.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{} } @@ -61,9 +62,15 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1beta1.LogPipeline) { if pipeline.Spec.Input.OTLP.Enabled == nil { pipeline.Spec.Input.OTLP.Enabled = &ld.OTLPInputEnabled } + + if ptr.Deref(pipeline.Spec.Input.OTLP.Enabled, false) && pipeline.Spec.Input.OTLP.Namespaces == nil { + pipeline.Spec.Input.OTLP.Namespaces = &telemetryv1beta1.NamespaceSelector{ + Exclude: ld.ExcludeNamespaces, + } + } } } -func isOTLPPipeline(pipeline *telemetryv1beta1.LogPipeline) bool { +func isOTLPPipelineBeta(pipeline *telemetryv1beta1.LogPipeline) bool { return pipeline.Spec.Output.OTLP != nil } diff --git a/webhook/logpipeline/v1beta1/defaulter_test.go b/webhook/logpipeline/v1beta1/defaulter_test.go index 731fda93c8..d2b89b9959 100644 --- a/webhook/logpipeline/v1beta1/defaulter_test.go +++ b/webhook/logpipeline/v1beta1/defaulter_test.go @@ -31,8 +31,8 @@ func TestDefault(t *testing.T) { Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{}, }, Output: telemetryv1beta1.LogPipelineOutput{ - OTLP: &telemetryv1beta1.OTLPOutput{ - Endpoint: telemetryv1beta1.ValueType{ + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ Value: "localhost:4317", }, }, @@ -42,9 +42,6 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ - OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), - }, Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: ptr.To(true), KeepOriginalBody: ptr.To(true), @@ -54,11 +51,10 @@ func TestDefault(t *testing.T) { }, }, Output: telemetryv1beta1.LogPipelineOutput{ - OTLP: &telemetryv1beta1.OTLPOutput{ - Endpoint: telemetryv1beta1.ValueType{ + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ Value: "localhost:4317", }, - Protocol: telemetryv1beta1.OTLPProtocolGRPC, }, }, }, @@ -74,11 +70,10 @@ func TestDefault(t *testing.T) { }, }, Output: telemetryv1beta1.LogPipelineOutput{ - OTLP: &telemetryv1beta1.OTLPOutput{ - Endpoint: telemetryv1beta1.ValueType{ + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ Value: "localhost:4317", }, - Protocol: telemetryv1beta1.OTLPProtocolGRPC, }, }, }, @@ -86,9 +81,6 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ - OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), - }, Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: ptr.To(true), KeepOriginalBody: ptr.To(false), @@ -98,11 +90,10 @@ func TestDefault(t *testing.T) { }, }, Output: telemetryv1beta1.LogPipelineOutput{ - OTLP: &telemetryv1beta1.OTLPOutput{ - Endpoint: telemetryv1beta1.ValueType{ + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ Value: "localhost:4317", }, - Protocol: telemetryv1beta1.OTLPProtocolGRPC, }, }, }, @@ -118,11 +109,10 @@ func TestDefault(t *testing.T) { }, }, Output: telemetryv1beta1.LogPipelineOutput{ - OTLP: &telemetryv1beta1.OTLPOutput{ - Endpoint: telemetryv1beta1.ValueType{ + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ Value: "localhost:4317", }, - Protocol: telemetryv1beta1.OTLPProtocolGRPC, }, }, }, @@ -130,26 +120,22 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ - OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), - }, Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ Enabled: ptr.To(false), }, }, Output: telemetryv1beta1.LogPipelineOutput{ - OTLP: &telemetryv1beta1.OTLPOutput{ - Endpoint: telemetryv1beta1.ValueType{ + HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ + Host: telemetryv1beta1.ValueType{ Value: "localhost:4317", }, - Protocol: telemetryv1beta1.OTLPProtocolGRPC, }, }, }, }, }, { - name: "should set default OTLPOutput if not set", + name: "should set default OTLPOutput protocol and OTLP Input namespaces if not set", input: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Output: telemetryv1beta1.LogPipelineOutput{ @@ -162,6 +148,9 @@ func TestDefault(t *testing.T) { Input: telemetryv1beta1.LogPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + }, }, }, Output: telemetryv1beta1.LogPipelineOutput{ @@ -173,9 +162,16 @@ func TestDefault(t *testing.T) { }, }, { - name: "should enable otlp input by default for OTLP output pipelines", + name: "should enable otlp input by default for OTLP output pipelines but do not override existing settings", input: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ + Input: telemetryv1beta1.LogPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"custom-namespace"}, + }, + }, + }, Output: telemetryv1beta1.LogPipelineOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ Endpoint: telemetryv1beta1.ValueType{ @@ -191,6 +187,9 @@ func TestDefault(t *testing.T) { Input: telemetryv1beta1.LogPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"custom-namespace"}, + }, }, }, Output: telemetryv1beta1.LogPipelineOutput{ diff --git a/webhook/metricpipeline/v1alpha1/defaulter.go b/webhook/metricpipeline/v1alpha1/defaulter.go index 84efa9995a..86d2124f7a 100644 --- a/webhook/metricpipeline/v1alpha1/defaulter.go +++ b/webhook/metricpipeline/v1alpha1/defaulter.go @@ -89,6 +89,14 @@ func (md defaulter) applyDefaults(pipeline *telemetryv1alpha1.MetricPipeline) { } } + if pipeline.Spec.Input.OTLP == nil { + pipeline.Spec.Input.OTLP = &telemetryv1alpha1.OTLPInput{} + } + + if pipeline.Spec.Input.OTLP.Namespaces == nil { + pipeline.Spec.Input.OTLP.Namespaces = &telemetryv1alpha1.NamespaceSelector{} + } + if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { pipeline.Spec.Output.OTLP.Protocol = md.DefaultOTLPOutputProtocol } diff --git a/webhook/metricpipeline/v1alpha1/defaulter_test.go b/webhook/metricpipeline/v1alpha1/defaulter_test.go index 8b04716495..5fa56263f4 100644 --- a/webhook/metricpipeline/v1alpha1/defaulter_test.go +++ b/webhook/metricpipeline/v1alpha1/defaulter_test.go @@ -31,7 +31,7 @@ func TestDefault(t *testing.T) { expected *telemetryv1alpha1.MetricPipeline }{ { - name: "should set default OTLP protocol if not set", + name: "should set default OTLP protocol and OTLP Input if not set", input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Output: telemetryv1alpha1.MetricPipelineOutput{ @@ -41,6 +41,11 @@ func TestDefault(t *testing.T) { }, expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ + Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, + }, Output: telemetryv1alpha1.MetricPipelineOutput{ OTLP: &telemetryv1alpha1.OTLPOutput{ Protocol: telemetryv1alpha1.OTLPProtocolGRPC, @@ -53,6 +58,11 @@ func TestDefault(t *testing.T) { name: "should not override existing OTLP protocol", input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ + Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, + }, Output: telemetryv1alpha1.MetricPipelineOutput{ OTLP: &telemetryv1alpha1.OTLPOutput{ Protocol: telemetryv1alpha1.OTLPProtocolHTTP, @@ -62,6 +72,11 @@ func TestDefault(t *testing.T) { }, expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ + Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, + }, Output: telemetryv1alpha1.MetricPipelineOutput{ OTLP: &telemetryv1alpha1.OTLPOutput{ Protocol: telemetryv1alpha1.OTLPProtocolHTTP, @@ -75,6 +90,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), }, @@ -84,6 +102,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ @@ -100,6 +121,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), }, @@ -109,6 +133,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ @@ -127,6 +154,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Runtime: &telemetryv1alpha1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), }, @@ -136,6 +166,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Runtime: &telemetryv1alpha1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ @@ -185,6 +218,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Runtime: &telemetryv1alpha1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Resources: &telemetryv1alpha1.MetricPipelineRuntimeInputResources{ @@ -199,6 +235,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Runtime: &telemetryv1alpha1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ @@ -247,6 +286,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(false), }, @@ -256,6 +298,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(false), }, @@ -277,6 +322,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(false), }, @@ -289,6 +337,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Runtime: &telemetryv1alpha1.MetricPipelineRuntimeInput{ Enabled: ptr.To(false), }, @@ -298,6 +349,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Runtime: &telemetryv1alpha1.MetricPipelineRuntimeInput{ Enabled: ptr.To(false), }, @@ -311,6 +365,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), }, @@ -320,6 +377,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ @@ -337,6 +397,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), }, @@ -346,6 +409,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ @@ -363,6 +429,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), EnvoyMetrics: &telemetryv1alpha1.EnvoyMetrics{Enabled: ptr.To(true)}, @@ -373,6 +442,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ @@ -390,6 +462,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), }, @@ -399,6 +474,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ @@ -415,6 +493,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), DiagnosticMetrics: &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(true)}, @@ -425,6 +506,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1alpha1.MetricPipeline{ Spec: telemetryv1alpha1.MetricPipelineSpec{ Input: telemetryv1alpha1.MetricPipelineInput{ + OTLP: &telemetryv1alpha1.OTLPInput{ + Namespaces: &telemetryv1alpha1.NamespaceSelector{}, + }, Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ diff --git a/webhook/metricpipeline/v1beta1/defaulter.go b/webhook/metricpipeline/v1beta1/defaulter.go index 64627b603a..b40b843d33 100644 --- a/webhook/metricpipeline/v1beta1/defaulter.go +++ b/webhook/metricpipeline/v1beta1/defaulter.go @@ -5,6 +5,7 @@ import ( "fmt" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/webhook" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" @@ -97,6 +98,12 @@ func (md defaulter) applyDefaults(pipeline *telemetryv1beta1.MetricPipeline) { pipeline.Spec.Input.OTLP.Enabled = &md.OTLPInputEnabled } + if ptr.Deref(pipeline.Spec.Input.OTLP.Enabled, false) && pipeline.Spec.Input.OTLP.Namespaces == nil { + pipeline.Spec.Input.OTLP.Namespaces = &telemetryv1beta1.NamespaceSelector{ + Exclude: md.ExcludeNamespaces, + } + } + if pipeline.Spec.Output.OTLP != nil && pipeline.Spec.Output.OTLP.Protocol == "" { pipeline.Spec.Output.OTLP.Protocol = md.DefaultOTLPOutputProtocol } diff --git a/webhook/metricpipeline/v1beta1/defaulter_test.go b/webhook/metricpipeline/v1beta1/defaulter_test.go index ac4062f88a..c4b4785142 100644 --- a/webhook/metricpipeline/v1beta1/defaulter_test.go +++ b/webhook/metricpipeline/v1beta1/defaulter_test.go @@ -32,7 +32,7 @@ func TestDefault(t *testing.T) { expected *telemetryv1beta1.MetricPipeline }{ { - name: "should set default OTLP protocol if not set", + name: "should set default OTLP protocol and otlp input if not set", input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Output: telemetryv1beta1.MetricPipelineOutput{ @@ -45,6 +45,9 @@ func TestDefault(t *testing.T) { Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + }, }, }, Output: telemetryv1beta1.MetricPipelineOutput{ @@ -59,6 +62,11 @@ func TestDefault(t *testing.T) { name: "should not override existing OTLP protocol", input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ + Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, + }, Output: telemetryv1beta1.MetricPipelineOutput{ OTLP: &telemetryv1beta1.OTLPOutput{ Protocol: telemetryv1beta1.OTLPProtocolHTTP, @@ -70,7 +78,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, }, Output: telemetryv1beta1.MetricPipelineOutput{ @@ -86,6 +94,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), }, @@ -96,7 +107,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), @@ -116,6 +127,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), }, @@ -126,7 +140,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), @@ -150,6 +164,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), }, @@ -160,7 +177,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), @@ -211,6 +228,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ @@ -226,7 +246,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), @@ -276,6 +296,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(false), }, @@ -286,7 +309,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(false), @@ -303,6 +326,9 @@ func TestDefault(t *testing.T) { Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + }, }, }, }, @@ -313,6 +339,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(false), }, @@ -323,7 +352,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(false), @@ -337,6 +366,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(false), }, @@ -347,7 +379,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(false), @@ -361,6 +393,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), EnvoyMetrics: &telemetryv1beta1.EnvoyMetrics{ @@ -374,7 +409,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), @@ -397,6 +432,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(true)}, @@ -408,7 +446,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), @@ -431,6 +469,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.MetricPipeline{ Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ + OTLP: &telemetryv1beta1.OTLPInput{ + Enabled: ptr.To(false), + }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(true)}, @@ -442,7 +483,7 @@ func TestDefault(t *testing.T) { Spec: telemetryv1beta1.MetricPipelineSpec{ Input: telemetryv1beta1.MetricPipelineInput{ OTLP: &telemetryv1beta1.OTLPInput{ - Enabled: ptr.To(true), + Enabled: ptr.To(false), }, Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), From 6d879bae6687a370389c5f725ebcc889e7111a52 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Tue, 21 Oct 2025 18:33:29 +0200 Subject: [PATCH 17/27] use more constants --- .../v1alpha1/logpipeline_conversion.go | 3 ++- .../v1alpha1/logpipeline_conversion_test.go | 3 ++- webhook/logpipeline/v1beta1/defaulter_test.go | 9 ++++---- webhook/logpipeline/v1beta1/setup.go | 3 ++- .../metricpipeline/v1alpha1/defaulter_test.go | 21 ++++++++++--------- webhook/metricpipeline/v1alpha1/setup.go | 3 ++- .../metricpipeline/v1beta1/defaulter_test.go | 21 ++++++++++--------- webhook/metricpipeline/v1beta1/setup.go | 3 ++- 8 files changed, 37 insertions(+), 29 deletions(-) diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index fd2289ca14..ff1a955623 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -6,6 +6,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/conversion" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + "github.com/kyma-project/telemetry-manager/internal/namespaces" ) var errSrcTypeUnsupportedLogPipeline = errors.New("source type is not LogPipeline v1alpha1") @@ -98,7 +99,7 @@ func convertApplicationToBeta(application *LogPipelineApplicationInput) *telemet var excludes []string if len(application.Namespaces.Include) == 0 && len(application.Namespaces.Exclude) == 0 && !application.Namespaces.System { - excludes = []string{"kyma-system", "kube-system", "istio-system", "compass-system"} + excludes = namespaces.System() } else { excludes = application.Namespaces.Exclude } diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion_test.go b/apis/telemetry/v1alpha1/logpipeline_conversion_test.go index 285baa05f6..cacebbbca3 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion_test.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion_test.go @@ -8,6 +8,7 @@ import ( "k8s.io/utils/ptr" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + "github.com/kyma-project/telemetry-manager/internal/namespaces" ) var v1alpha1LogPipeline = &LogPipeline{ @@ -364,7 +365,7 @@ func TestLogPipelineConvertTo(t *testing.T) { Input: telemetryv1beta1.LogPipelineInput{ Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, }, }, diff --git a/webhook/logpipeline/v1beta1/defaulter_test.go b/webhook/logpipeline/v1beta1/defaulter_test.go index d2b89b9959..76b50bfa9a 100644 --- a/webhook/logpipeline/v1beta1/defaulter_test.go +++ b/webhook/logpipeline/v1beta1/defaulter_test.go @@ -7,11 +7,12 @@ import ( "k8s.io/utils/ptr" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + "github.com/kyma-project/telemetry-manager/internal/namespaces" ) func TestDefault(t *testing.T) { sut := defaulter{ - ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + ExcludeNamespaces: namespaces.System(), RuntimeInputEnabled: true, RuntimeInputKeepOriginalBody: true, DefaultOTLPOutputProtocol: telemetryv1beta1.OTLPProtocolGRPC, @@ -46,7 +47,7 @@ func TestDefault(t *testing.T) { Enabled: ptr.To(true), KeepOriginalBody: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, }, }, @@ -85,7 +86,7 @@ func TestDefault(t *testing.T) { Enabled: ptr.To(true), KeepOriginalBody: ptr.To(false), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, }, }, @@ -149,7 +150,7 @@ func TestDefault(t *testing.T) { OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, }, }, diff --git a/webhook/logpipeline/v1beta1/setup.go b/webhook/logpipeline/v1beta1/setup.go index b655095cc5..d63cef6927 100644 --- a/webhook/logpipeline/v1beta1/setup.go +++ b/webhook/logpipeline/v1beta1/setup.go @@ -4,12 +4,13 @@ import ( ctrl "sigs.k8s.io/controller-runtime" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + "github.com/kyma-project/telemetry-manager/internal/namespaces" ) func SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr).For(&telemetryv1beta1.LogPipeline{}). WithDefaulter(&defaulter{ - ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + ExcludeNamespaces: namespaces.System(), RuntimeInputEnabled: true, RuntimeInputKeepOriginalBody: true, DefaultOTLPOutputProtocol: telemetryv1beta1.OTLPProtocolGRPC, diff --git a/webhook/metricpipeline/v1alpha1/defaulter_test.go b/webhook/metricpipeline/v1alpha1/defaulter_test.go index 5fa56263f4..76212d1ae1 100644 --- a/webhook/metricpipeline/v1alpha1/defaulter_test.go +++ b/webhook/metricpipeline/v1alpha1/defaulter_test.go @@ -7,11 +7,12 @@ import ( "k8s.io/utils/ptr" telemetryv1alpha1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1alpha1" + "github.com/kyma-project/telemetry-manager/internal/namespaces" ) func TestDefault(t *testing.T) { sut := defaulter{ - ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + ExcludeNamespaces: namespaces.System(), RuntimeInputResources: runtimeInputResourceDefaults{ Pod: true, Container: true, @@ -108,7 +109,7 @@ func TestDefault(t *testing.T) { Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(false)}, }, @@ -139,7 +140,7 @@ func TestDefault(t *testing.T) { Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(false)}, EnvoyMetrics: &telemetryv1alpha1.EnvoyMetrics{Enabled: ptr.To(false)}, @@ -172,7 +173,7 @@ func TestDefault(t *testing.T) { Runtime: &telemetryv1alpha1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, Resources: &telemetryv1alpha1.MetricPipelineRuntimeInputResources{ Pod: &telemetryv1alpha1.MetricPipelineRuntimeInputResource{ @@ -241,7 +242,7 @@ func TestDefault(t *testing.T) { Runtime: &telemetryv1alpha1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, Resources: &telemetryv1alpha1.MetricPipelineRuntimeInputResources{ Pod: &telemetryv1alpha1.MetricPipelineRuntimeInputResource{ @@ -383,7 +384,7 @@ func TestDefault(t *testing.T) { Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(false)}, EnvoyMetrics: &telemetryv1alpha1.EnvoyMetrics{Enabled: ptr.To(false)}, @@ -415,7 +416,7 @@ func TestDefault(t *testing.T) { Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(false)}, EnvoyMetrics: &telemetryv1alpha1.EnvoyMetrics{Enabled: ptr.To(false)}, @@ -448,7 +449,7 @@ func TestDefault(t *testing.T) { Istio: &telemetryv1alpha1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(false)}, EnvoyMetrics: &telemetryv1alpha1.EnvoyMetrics{Enabled: ptr.To(true)}, @@ -480,7 +481,7 @@ func TestDefault(t *testing.T) { Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(false)}, }, @@ -512,7 +513,7 @@ func TestDefault(t *testing.T) { Prometheus: &telemetryv1alpha1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1alpha1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1alpha1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(true)}, }, diff --git a/webhook/metricpipeline/v1alpha1/setup.go b/webhook/metricpipeline/v1alpha1/setup.go index fb157f63d5..7692f896fd 100644 --- a/webhook/metricpipeline/v1alpha1/setup.go +++ b/webhook/metricpipeline/v1alpha1/setup.go @@ -4,12 +4,13 @@ import ( ctrl "sigs.k8s.io/controller-runtime" telemetryv1alpha1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1alpha1" + "github.com/kyma-project/telemetry-manager/internal/namespaces" ) func SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr).For(&telemetryv1alpha1.MetricPipeline{}). WithDefaulter(&defaulter{ - ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + ExcludeNamespaces: namespaces.System(), RuntimeInputResources: runtimeInputResourceDefaults{ Pod: true, Container: true, diff --git a/webhook/metricpipeline/v1beta1/defaulter_test.go b/webhook/metricpipeline/v1beta1/defaulter_test.go index c4b4785142..34afb66792 100644 --- a/webhook/metricpipeline/v1beta1/defaulter_test.go +++ b/webhook/metricpipeline/v1beta1/defaulter_test.go @@ -7,11 +7,12 @@ import ( "k8s.io/utils/ptr" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + "github.com/kyma-project/telemetry-manager/internal/namespaces" ) func TestDefault(t *testing.T) { sut := defaulter{ - ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + ExcludeNamespaces: namespaces.System(), OTLPInputEnabled: true, RuntimeInputResources: runtimeInputResourceDefaults{ Pod: true, @@ -46,7 +47,7 @@ func TestDefault(t *testing.T) { OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, }, }, @@ -112,7 +113,7 @@ func TestDefault(t *testing.T) { Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{ Enabled: ptr.To(false), @@ -145,7 +146,7 @@ func TestDefault(t *testing.T) { Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, EnvoyMetrics: &telemetryv1beta1.EnvoyMetrics{ Enabled: ptr.To(false), @@ -182,7 +183,7 @@ func TestDefault(t *testing.T) { Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ @@ -251,7 +252,7 @@ func TestDefault(t *testing.T) { Runtime: &telemetryv1beta1.MetricPipelineRuntimeInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, Resources: &telemetryv1beta1.MetricPipelineRuntimeInputResources{ Pod: &telemetryv1beta1.MetricPipelineRuntimeInputResource{ @@ -327,7 +328,7 @@ func TestDefault(t *testing.T) { OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, }, }, @@ -414,7 +415,7 @@ func TestDefault(t *testing.T) { Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, EnvoyMetrics: &telemetryv1beta1.EnvoyMetrics{ Enabled: ptr.To(true), @@ -451,7 +452,7 @@ func TestDefault(t *testing.T) { Istio: &telemetryv1beta1.MetricPipelineIstioInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, EnvoyMetrics: &telemetryv1beta1.EnvoyMetrics{ Enabled: ptr.To(false), @@ -488,7 +489,7 @@ func TestDefault(t *testing.T) { Prometheus: &telemetryv1beta1.MetricPipelinePrometheusInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ - Exclude: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + Exclude: namespaces.System(), }, DiagnosticMetrics: &telemetryv1beta1.MetricPipelineIstioInputDiagnosticMetrics{Enabled: ptr.To(true)}, }, diff --git a/webhook/metricpipeline/v1beta1/setup.go b/webhook/metricpipeline/v1beta1/setup.go index ea8ccc10d5..6de041fd49 100644 --- a/webhook/metricpipeline/v1beta1/setup.go +++ b/webhook/metricpipeline/v1beta1/setup.go @@ -4,12 +4,13 @@ import ( ctrl "sigs.k8s.io/controller-runtime" telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" + "github.com/kyma-project/telemetry-manager/internal/namespaces" ) func SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr).For(&telemetryv1beta1.MetricPipeline{}). WithDefaulter(&defaulter{ - ExcludeNamespaces: []string{"kyma-system", "kube-system", "istio-system", "compass-system"}, + ExcludeNamespaces: namespaces.System(), RuntimeInputResources: runtimeInputResourceDefaults{ Pod: true, Container: true, From 412c581fdcebbfe932f807e6672c048098b8dac5 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Thu, 23 Oct 2025 14:09:10 +0200 Subject: [PATCH 18/27] docu fix --- apis/telemetry/v1alpha1/metricpipeline_types.go | 2 +- apis/telemetry/v1beta1/metricpipeline_types.go | 2 +- apis/telemetry/v1beta1/shared_types.go | 2 +- docs/user/resources/05-metricpipeline.md | 2 +- .../telemetry.kyma-project.io_metricpipelines.yaml | 2 +- .../telemetry.kyma-project.io_logpipelines.yaml | 7 ++++--- .../telemetry.kyma-project.io_metricpipelines.yaml | 13 ++++++++----- 7 files changed, 17 insertions(+), 13 deletions(-) diff --git a/apis/telemetry/v1alpha1/metricpipeline_types.go b/apis/telemetry/v1alpha1/metricpipeline_types.go index f82db79ab3..5c7e3bdf36 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_types.go +++ b/apis/telemetry/v1alpha1/metricpipeline_types.go @@ -158,7 +158,7 @@ type MetricPipelineIstioInput struct { // Enabled specifies if the 'istio' input is enabled. If enabled, istio-proxy metrics are scraped from Pods that have the istio-proxy sidecar injected. The default is `false`. // +kubebuilder:validation:Optional Enabled *bool `json:"enabled,omitempty"` - // Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces including system namespaces are enabled. + // Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces excluding system namespaces are enabled. To enable all namespaces including system namespaces, use an empty struct notation. // +kubebuilder:validation:Optional Namespaces *NamespaceSelector `json:"namespaces,omitempty"` // DiagnosticMetrics configures collection of additional diagnostic metrics. The default is `false`. diff --git a/apis/telemetry/v1beta1/metricpipeline_types.go b/apis/telemetry/v1beta1/metricpipeline_types.go index f853cffee9..77ba1d49b8 100644 --- a/apis/telemetry/v1beta1/metricpipeline_types.go +++ b/apis/telemetry/v1beta1/metricpipeline_types.go @@ -159,7 +159,7 @@ type MetricPipelineIstioInput struct { // Enabled specifies if the 'istio' input is enabled. If enabled, istio-proxy metrics are scraped from Pods that have the istio-proxy sidecar injected. The default is `false`. // +kubebuilder:validation:Optional Enabled *bool `json:"enabled,omitempty"` - // Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces including system namespaces are enabled. + // Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces excluding system namespaces are enabled. To enable all namespaces including system namespaces, use an empty struct notation. // +kubebuilder:validation:Optional Namespaces *NamespaceSelector `json:"namespaces,omitempty"` // DiagnosticMetrics configures collection of additional diagnostic metrics. The default is `false`. diff --git a/apis/telemetry/v1beta1/shared_types.go b/apis/telemetry/v1beta1/shared_types.go index 9f82d83293..3e52ba51ea 100644 --- a/apis/telemetry/v1beta1/shared_types.go +++ b/apis/telemetry/v1beta1/shared_types.go @@ -118,7 +118,7 @@ type OTLPInput struct { // Enabled specifies if the 'otlp' input is enabled. If enabled, then push-based OTLP signals are collected. The default is `true`. // +kubebuilder:validation:Optional Enabled *bool `json:"enabled,omitempty"` - // Namespaces describes whether push-based OTLP signals from specific namespaces are selected. System namespaces are enabled by default. + // Namespaces describe whether push-based OTLP signals from specific namespaces are selected. By default, all namespaces excluding system namespaces are enabled. To enable all namespaces including system namespaces, use an empty struct notation. // +kubebuilder:validation:Optional Namespaces *NamespaceSelector `json:"namespaces,omitempty"` } diff --git a/docs/user/resources/05-metricpipeline.md b/docs/user/resources/05-metricpipeline.md index 9d0a3f0b2f..33a2213440 100644 --- a/docs/user/resources/05-metricpipeline.md +++ b/docs/user/resources/05-metricpipeline.md @@ -75,7 +75,7 @@ For details, see the [MetricPipeline specification file](https://github.com/kyma | **input.​istio.​enabled** | boolean | Enabled specifies if the 'istio' input is enabled. If enabled, istio-proxy metrics are scraped from Pods that have the istio-proxy sidecar injected. The default is `false`. | | **input.​istio.​envoyMetrics** | object | EnvoyMetrics enables the collection of additional Envoy metrics with prefix `envoy_`. The default is `false`. | | **input.​istio.​envoyMetrics.​enabled** | boolean | Enabled specifies that Envoy metrics with prefix `envoy_` are scraped additionally. The default is `false`. | -| **input.​istio.​namespaces** | object | Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces including system namespaces are enabled. | +| **input.​istio.​namespaces** | object | Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces excluding system namespaces are enabled. To enable all namespaces including system namespaces, use an empty struct notation. | | **input.​istio.​namespaces.​exclude** | \[\]string | Exclude telemetry data from the specified namespace names only. By default, all namespaces (depending on input type: except system namespaces) are collected. You cannot specify an exclude list together with an include list. | | **input.​istio.​namespaces.​include** | \[\]string | Include telemetry data from the specified namespace names only. By default, all namespaces (depending on input type: except system namespaces) are included. You cannot specify an include list together with an exclude list. | | **input.​otlp** | object | OTLP input configures the push endpoint to receive metrics from an OTLP source. | diff --git a/helm/charts/default/templates/telemetry.kyma-project.io_metricpipelines.yaml b/helm/charts/default/templates/telemetry.kyma-project.io_metricpipelines.yaml index 4dec73cf13..d64db81301 100644 --- a/helm/charts/default/templates/telemetry.kyma-project.io_metricpipelines.yaml +++ b/helm/charts/default/templates/telemetry.kyma-project.io_metricpipelines.yaml @@ -88,7 +88,7 @@ spec: type: boolean type: object namespaces: - description: Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces including system namespaces are enabled. + description: Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces excluding system namespaces are enabled. To enable all namespaces including system namespaces, use an empty struct notation. properties: exclude: description: 'Exclude telemetry data from the specified namespace names only. By default, all namespaces (depending on input type: except system namespaces) are collected. You cannot specify an exclude list together with an include list.' diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml index ef3e76780a..daafc51ac7 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_logpipelines.yaml @@ -1261,9 +1261,10 @@ spec: The default is `true`. type: boolean namespaces: - description: Namespaces describes whether push-based OTLP - signals from specific namespaces are selected. System namespaces - are enabled by default. + description: Namespaces describe whether push-based OTLP signals + from specific namespaces are selected. By default, all namespaces + excluding system namespaces are enabled. To enable all namespaces + including system namespaces, use an empty struct notation. properties: exclude: description: 'Exclude telemetry data from the specified diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml index 157a84969b..8a58db785f 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml @@ -116,7 +116,8 @@ spec: namespaces: description: Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces - including system namespaces are enabled. + excluding system namespaces are enabled. To enable all namespaces + including system namespaces, use an empty struct notation. properties: exclude: description: 'Exclude telemetry data from the specified @@ -940,7 +941,8 @@ spec: namespaces: description: Namespaces configures the namespaces for which the collection should be activated. By default, all namespaces - including system namespaces are enabled. + excluding system namespaces are enabled. To enable all namespaces + including system namespaces, use an empty struct notation. properties: exclude: description: 'Exclude telemetry data from the specified @@ -979,9 +981,10 @@ spec: The default is `true`. type: boolean namespaces: - description: Namespaces describes whether push-based OTLP - signals from specific namespaces are selected. System namespaces - are enabled by default. + description: Namespaces describe whether push-based OTLP signals + from specific namespaces are selected. By default, all namespaces + excluding system namespaces are enabled. To enable all namespaces + including system namespaces, use an empty struct notation. properties: exclude: description: 'Exclude telemetry data from the specified From 8d96a470e8d1f72ddcfb2ef026c79ef7202c66b8 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Thu, 23 Oct 2025 15:07:46 +0200 Subject: [PATCH 19/27] fix --- .../v1alpha1/logpipeline_conversion.go | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index ff1a955623..5a604e6f92 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -111,8 +111,8 @@ func convertApplicationToBeta(application *LogPipelineApplicationInput) *telemet Exclude: sanitizeNamespaceNames(excludes), }, Containers: telemetryv1beta1.LogPipelineContainerSelector{ - Include: application.Containers.Include, - Exclude: application.Containers.Exclude, + Include: append([]string{}, application.Containers.Include...), + Exclude: append([]string{}, application.Containers.Exclude...), }, KeepAnnotations: application.KeepAnnotations, DropLabels: application.DropLabels, @@ -221,20 +221,23 @@ func convertRuntimeToAlpha(runtime *telemetryv1beta1.LogPipelineRuntimeInput) *L application := &LogPipelineApplicationInput{ Enabled: runtime.Enabled, - Namespaces: LogPipelineNamespaceSelector{ - Include: runtime.Namespaces.Include, - Exclude: runtime.Namespaces.Exclude, - System: false, - }, Containers: LogPipelineContainerSelector{ - Include: runtime.Containers.Include, - Exclude: runtime.Containers.Exclude, + Include: append([]string{}, runtime.Containers.Include...), + Exclude: append([]string{}, runtime.Containers.Exclude...), }, KeepAnnotations: runtime.KeepAnnotations, DropLabels: runtime.DropLabels, KeepOriginalBody: runtime.KeepOriginalBody, } + if runtime.Namespaces != nil { + application.Namespaces = LogPipelineNamespaceSelector{ + Include: append([]string{}, runtime.Namespaces.Include...), + Exclude: append([]string{}, runtime.Namespaces.Exclude...), + System: false, + } + } + return application } From 3c5ee09203cdd0a39ac11e732c8e3c4726b1bff6 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Thu, 23 Oct 2025 15:55:50 +0200 Subject: [PATCH 20/27] fixed conversion --- .../v1alpha1/logpipeline_conversion.go | 44 +++++++++++-------- .../v1alpha1/logpipeline_conversion_test.go | 2 +- apis/telemetry/v1beta1/logpipeline_types.go | 2 +- .../v1beta1/zz_generated.deepcopy.go | 6 ++- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index 5a604e6f92..58ead7eb6a 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -97,6 +97,13 @@ func convertApplicationToBeta(application *LogPipelineApplicationInput) *telemet return nil } + runtime := &telemetryv1beta1.LogPipelineRuntimeInput{ + Enabled: application.Enabled, + KeepAnnotations: application.KeepAnnotations, + DropLabels: application.DropLabels, + KeepOriginalBody: application.KeepOriginalBody, + } + var excludes []string if len(application.Namespaces.Include) == 0 && len(application.Namespaces.Exclude) == 0 && !application.Namespaces.System { excludes = namespaces.System() @@ -104,19 +111,17 @@ func convertApplicationToBeta(application *LogPipelineApplicationInput) *telemet excludes = application.Namespaces.Exclude } - runtime := &telemetryv1beta1.LogPipelineRuntimeInput{ - Enabled: application.Enabled, - Namespaces: &telemetryv1beta1.NamespaceSelector{ - Include: sanitizeNamespaceNames(application.Namespaces.Include), - Exclude: sanitizeNamespaceNames(excludes), - }, - Containers: telemetryv1beta1.LogPipelineContainerSelector{ - Include: append([]string{}, application.Containers.Include...), - Exclude: append([]string{}, application.Containers.Exclude...), - }, - KeepAnnotations: application.KeepAnnotations, - DropLabels: application.DropLabels, - KeepOriginalBody: application.KeepOriginalBody, + runtime.Namespaces = &telemetryv1beta1.NamespaceSelector{ + Include: sanitizeNamespaceNames(application.Namespaces.Include), + Exclude: sanitizeNamespaceNames(excludes), + } + + if len(application.Containers.Include) > 0 || len(application.Containers.Exclude) > 0 { + runtime.Containers = + &telemetryv1beta1.LogPipelineContainerSelector{ + Include: append([]string{}, application.Containers.Include...), + Exclude: append([]string{}, application.Containers.Exclude...), + } } return runtime @@ -220,11 +225,7 @@ func convertRuntimeToAlpha(runtime *telemetryv1beta1.LogPipelineRuntimeInput) *L } application := &LogPipelineApplicationInput{ - Enabled: runtime.Enabled, - Containers: LogPipelineContainerSelector{ - Include: append([]string{}, runtime.Containers.Include...), - Exclude: append([]string{}, runtime.Containers.Exclude...), - }, + Enabled: runtime.Enabled, KeepAnnotations: runtime.KeepAnnotations, DropLabels: runtime.DropLabels, KeepOriginalBody: runtime.KeepOriginalBody, @@ -238,6 +239,13 @@ func convertRuntimeToAlpha(runtime *telemetryv1beta1.LogPipelineRuntimeInput) *L } } + if runtime.Containers != nil { + application.Containers = LogPipelineContainerSelector{ + Include: append([]string{}, runtime.Containers.Include...), + Exclude: append([]string{}, runtime.Containers.Exclude...), + } + } + return application } diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion_test.go b/apis/telemetry/v1alpha1/logpipeline_conversion_test.go index cacebbbca3..4d1c07cb80 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion_test.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion_test.go @@ -167,7 +167,7 @@ var v1beta1LogPipeline = &telemetryv1beta1.LogPipeline{ Include: []string{"default", "kube-system"}, Exclude: []string{"kube-public"}, }, - Containers: telemetryv1beta1.LogPipelineContainerSelector{ + Containers: &telemetryv1beta1.LogPipelineContainerSelector{ Include: []string{"nginx", "app"}, Exclude: []string{"sidecar"}, }, diff --git a/apis/telemetry/v1beta1/logpipeline_types.go b/apis/telemetry/v1beta1/logpipeline_types.go index bc70476098..db00b04cb8 100644 --- a/apis/telemetry/v1beta1/logpipeline_types.go +++ b/apis/telemetry/v1beta1/logpipeline_types.go @@ -118,7 +118,7 @@ type LogPipelineRuntimeInput struct { Namespaces *NamespaceSelector `json:"namespaces,omitempty"` // Containers describes whether application logs from specific containers are selected. The options are mutually exclusive. // +kubebuilder:validation:Optional - Containers LogPipelineContainerSelector `json:"containers,omitempty"` + Containers *LogPipelineContainerSelector `json:"containers,omitempty"` // KeepAnnotations defines whether to keep all Kubernetes annotations. The default is `false`. Only available when using an output of type `http` and `custom`. // +kubebuilder:validation:Optional KeepAnnotations *bool `json:"keepAnnotations,omitempty"` diff --git a/apis/telemetry/v1beta1/zz_generated.deepcopy.go b/apis/telemetry/v1beta1/zz_generated.deepcopy.go index 23b4c83140..8f904d5105 100644 --- a/apis/telemetry/v1beta1/zz_generated.deepcopy.go +++ b/apis/telemetry/v1beta1/zz_generated.deepcopy.go @@ -322,7 +322,11 @@ func (in *LogPipelineRuntimeInput) DeepCopyInto(out *LogPipelineRuntimeInput) { *out = new(NamespaceSelector) (*in).DeepCopyInto(*out) } - in.Containers.DeepCopyInto(&out.Containers) + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = new(LogPipelineContainerSelector) + (*in).DeepCopyInto(*out) + } if in.KeepAnnotations != nil { in, out := &in.KeepAnnotations, &out.KeepAnnotations *out = new(bool) From 11a68e5f9d7215981a5e7e4d7405d5cda44dc582 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 27 Oct 2025 11:02:37 +0100 Subject: [PATCH 21/27] fixes --- webhook/logpipeline/v1alpha1/defaulter.go | 4 +-- webhook/logpipeline/v1beta1/defaulter.go | 29 +++++++++++-------- webhook/logpipeline/v1beta1/defaulter_test.go | 25 ++++++++++++++-- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/webhook/logpipeline/v1alpha1/defaulter.go b/webhook/logpipeline/v1alpha1/defaulter.go index adf5d2eb69..5696bbf5fa 100644 --- a/webhook/logpipeline/v1alpha1/defaulter.go +++ b/webhook/logpipeline/v1alpha1/defaulter.go @@ -46,7 +46,7 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1alpha1.LogPipeline) { pipeline.Spec.Input.Application.KeepOriginalBody = &ld.ApplicationInputKeepOriginalBody } - if isOTLPPipelineAlpha(pipeline) { + if isOTLPPipeline(pipeline) { if pipeline.Spec.Input.OTLP == nil { pipeline.Spec.Input.OTLP = &telemetryv1alpha1.OTLPInput{} } @@ -61,6 +61,6 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1alpha1.LogPipeline) { } } -func isOTLPPipelineAlpha(pipeline *telemetryv1alpha1.LogPipeline) bool { +func isOTLPPipeline(pipeline *telemetryv1alpha1.LogPipeline) bool { return pipeline.Spec.Output.OTLP != nil } diff --git a/webhook/logpipeline/v1beta1/defaulter.go b/webhook/logpipeline/v1beta1/defaulter.go index b6a75087f6..11a1364f83 100644 --- a/webhook/logpipeline/v1beta1/defaulter.go +++ b/webhook/logpipeline/v1beta1/defaulter.go @@ -34,19 +34,24 @@ func (ld defaulter) Default(ctx context.Context, obj runtime.Object) error { } func (ld defaulter) applyDefaults(pipeline *telemetryv1beta1.LogPipeline) { - if pipeline.Spec.Input.Runtime != nil { - if pipeline.Spec.Input.Runtime.Enabled == nil { - pipeline.Spec.Input.Runtime.Enabled = &ld.RuntimeInputEnabled + if pipeline.Spec.Input.Runtime == nil { + pipeline.Spec.Input.Runtime = &telemetryv1beta1.LogPipelineRuntimeInput{ + Enabled: &ld.RuntimeInputEnabled, + KeepOriginalBody: &ld.RuntimeInputKeepOriginalBody, } + } - if *pipeline.Spec.Input.Runtime.Enabled && pipeline.Spec.Input.Runtime.KeepOriginalBody == nil { - pipeline.Spec.Input.Runtime.KeepOriginalBody = &ld.RuntimeInputKeepOriginalBody - } + if pipeline.Spec.Input.Runtime.Enabled == nil { + pipeline.Spec.Input.Runtime.Enabled = &ld.RuntimeInputEnabled + } - if *pipeline.Spec.Input.Runtime.Enabled && pipeline.Spec.Input.Runtime.Namespaces == nil { - pipeline.Spec.Input.Runtime.Namespaces = &telemetryv1beta1.NamespaceSelector{ - Exclude: ld.ExcludeNamespaces, - } + if *pipeline.Spec.Input.Runtime.Enabled && pipeline.Spec.Input.Runtime.KeepOriginalBody == nil { + pipeline.Spec.Input.Runtime.KeepOriginalBody = &ld.RuntimeInputKeepOriginalBody + } + + if *pipeline.Spec.Input.Runtime.Enabled && pipeline.Spec.Input.Runtime.Namespaces == nil { + pipeline.Spec.Input.Runtime.Namespaces = &telemetryv1beta1.NamespaceSelector{ + Exclude: ld.ExcludeNamespaces, } } @@ -54,7 +59,7 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1beta1.LogPipeline) { pipeline.Spec.Output.OTLP.Protocol = ld.DefaultOTLPOutputProtocol } - if isOTLPPipelineBeta(pipeline) { + if isOTLPPipeline(pipeline) { if pipeline.Spec.Input.OTLP == nil { pipeline.Spec.Input.OTLP = &telemetryv1beta1.OTLPInput{} } @@ -71,6 +76,6 @@ func (ld defaulter) applyDefaults(pipeline *telemetryv1beta1.LogPipeline) { } } -func isOTLPPipelineBeta(pipeline *telemetryv1beta1.LogPipeline) bool { +func isOTLPPipeline(pipeline *telemetryv1beta1.LogPipeline) bool { return pipeline.Spec.Output.OTLP != nil } diff --git a/webhook/logpipeline/v1beta1/defaulter_test.go b/webhook/logpipeline/v1beta1/defaulter_test.go index 76b50bfa9a..5f26bdb013 100644 --- a/webhook/logpipeline/v1beta1/defaulter_test.go +++ b/webhook/logpipeline/v1beta1/defaulter_test.go @@ -147,6 +147,13 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Enabled: ptr.To(true), + KeepOriginalBody: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: namespaces.System(), + }, + }, OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ @@ -167,6 +174,9 @@ func TestDefault(t *testing.T) { input: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Enabled: ptr.To(false), + }, OTLP: &telemetryv1beta1.OTLPInput{ Namespaces: &telemetryv1beta1.NamespaceSelector{ Exclude: []string{"custom-namespace"}, @@ -186,6 +196,9 @@ func TestDefault(t *testing.T) { expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Enabled: ptr.To(false), + }, OTLP: &telemetryv1beta1.OTLPInput{ Enabled: ptr.To(true), Namespaces: &telemetryv1beta1.NamespaceSelector{ @@ -205,7 +218,7 @@ func TestDefault(t *testing.T) { }, }, { - name: "should not activate otlp input by default for non-OTLP output pipelines", + name: "should not activate otlp input by default for non-OTLP output pipelines, but runtime input", input: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ Output: telemetryv1beta1.LogPipelineOutput{ @@ -219,7 +232,15 @@ func TestDefault(t *testing.T) { }, expected: &telemetryv1beta1.LogPipeline{ Spec: telemetryv1beta1.LogPipelineSpec{ - Input: telemetryv1beta1.LogPipelineInput{}, + Input: telemetryv1beta1.LogPipelineInput{ + Runtime: &telemetryv1beta1.LogPipelineRuntimeInput{ + Enabled: ptr.To(true), + KeepOriginalBody: ptr.To(true), + Namespaces: &telemetryv1beta1.NamespaceSelector{ + Exclude: namespaces.System(), + }, + }, + }, Output: telemetryv1beta1.LogPipelineOutput{ HTTP: &telemetryv1beta1.LogPipelineHTTPOutput{ Host: telemetryv1beta1.ValueType{ From 078019c28e101241c162d2ceac4a459ce44f7f9a Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Tue, 28 Oct 2025 15:38:46 +0100 Subject: [PATCH 22/27] added more docu --- apis/telemetry/v1alpha1/groupversion_info.go | 16 ---------------- apis/telemetry/v1alpha1/logparser_types.go | 16 ---------------- .../v1alpha1/logpipeline_conversion.go | 8 ++++++++ apis/telemetry/v1alpha1/logpipeline_types.go | 16 ---------------- .../v1alpha1/metricpipeline_conversion.go | 4 ++++ .../telemetry/v1alpha1/metricpipeline_types.go | 18 +----------------- .../v1alpha1/shared_types_conversion.go | 6 ++++++ apis/telemetry/v1alpha1/tracepipeline_types.go | 18 +----------------- apis/telemetry/v1beta1/groupversion_info.go | 16 ---------------- apis/telemetry/v1beta1/logpipeline_types.go | 16 ---------------- apis/telemetry/v1beta1/metricpipeline_types.go | 16 ---------------- apis/telemetry/v1beta1/tracepipeline_types.go | 18 +----------------- .../telemetry/v1beta1/zz_generated.deepcopy.go | 4 ++-- ...emetry.kyma-project.io_metricpipelines.yaml | 2 +- ...lemetry.kyma-project.io_tracepipelines.yaml | 2 +- 15 files changed, 25 insertions(+), 151 deletions(-) diff --git a/apis/telemetry/v1alpha1/groupversion_info.go b/apis/telemetry/v1alpha1/groupversion_info.go index 2ad0488684..198f98b724 100644 --- a/apis/telemetry/v1alpha1/groupversion_info.go +++ b/apis/telemetry/v1alpha1/groupversion_info.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1alpha1 contains API Schema definitions for the telemetry v1alpha1 API group // +kubebuilder:object:generate=true // +groupName=telemetry.kyma-project.io diff --git a/apis/telemetry/v1alpha1/logparser_types.go b/apis/telemetry/v1alpha1/logparser_types.go index b4d4116420..881d82a3b8 100644 --- a/apis/telemetry/v1alpha1/logparser_types.go +++ b/apis/telemetry/v1alpha1/logparser_types.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1alpha1 import ( diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index 58ead7eb6a..e07ff12aa1 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -9,6 +9,14 @@ import ( "github.com/kyma-project/telemetry-manager/internal/namespaces" ) +// Converts between v1alpha1 and v1beta1 LogPipeline CRDs +// Major API changes which require specific conversion logic are: +// - input.application (v1alpha1) is renamed to input.runtime (v1beta1). +// - NamespaceSelector in input.runtime (v1beta1) is using the shared selector of input.otlp which lead to not having a 'System' boolean field anymore. +// - output.http in v1beta1 is using the shared TLS section of the output.otlp, leading to a rename of 'Disabled' field to 'Insecure' and 'SkipCertificateValidation' to 'InsecureSkipVerify'. +// - input.runtime namespaces and containers are now pointers in v1beta1, requiring nil checks during conversion. +// Additionally, changes were done in shared types which are documented in the related file. + var errSrcTypeUnsupportedLogPipeline = errors.New("source type is not LogPipeline v1alpha1") var errDstTypeUnsupportedLogPipeline = errors.New("destination type is not LogPipeline v1beta1") diff --git a/apis/telemetry/v1alpha1/logpipeline_types.go b/apis/telemetry/v1alpha1/logpipeline_types.go index 54e3f2759b..bd0a124c83 100644 --- a/apis/telemetry/v1alpha1/logpipeline_types.go +++ b/apis/telemetry/v1alpha1/logpipeline_types.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1alpha1 import ( diff --git a/apis/telemetry/v1alpha1/metricpipeline_conversion.go b/apis/telemetry/v1alpha1/metricpipeline_conversion.go index 98d928291e..3c529e69d9 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/metricpipeline_conversion.go @@ -8,6 +8,10 @@ import ( telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" ) +// Converts between v1alpha1 and v1beta1 MetricPipeline CRDs +// There are no major changes to the MetricPipeline API between v1alpha1 and v1beta1. +// However, some changes were done in shared types which are documented in the related file and require to convert MetricPipelines. + var errSrcTypeUnsupportedMetricPipeline = errors.New("source type is not MetricPipeline v1alpha1") var errDstTypeUnsupportedMetricPipeline = errors.New("destination type is not MetricPipeline v1beta1") diff --git a/apis/telemetry/v1alpha1/metricpipeline_types.go b/apis/telemetry/v1alpha1/metricpipeline_types.go index 5c7e3bdf36..daf2bc2e6a 100644 --- a/apis/telemetry/v1alpha1/metricpipeline_types.go +++ b/apis/telemetry/v1alpha1/metricpipeline_types.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1alpha1 import ( @@ -71,7 +55,7 @@ type MetricPipelineSpec struct { // +kubebuilder:validation:Optional Transforms []TransformSpec `json:"transform,omitempty"` - // Filters specifies a list of filters to apply to telemetry data. + // Filter specifies a list of filters to apply to telemetry data. // +kubebuilder:validation:Optional Filters []FilterSpec `json:"filter,omitempty"` } diff --git a/apis/telemetry/v1alpha1/shared_types_conversion.go b/apis/telemetry/v1alpha1/shared_types_conversion.go index c1bdb3d490..57ee5e0445 100644 --- a/apis/telemetry/v1alpha1/shared_types_conversion.go +++ b/apis/telemetry/v1alpha1/shared_types_conversion.go @@ -8,6 +8,12 @@ import ( telemetryv1beta1 "github.com/kyma-project/telemetry-manager/apis/telemetry/v1beta1" ) +// Converts shared structs between v1alpha1 and v1beta1 CRDs. +// Major API changes which require specific conversion logic are: +// - input.otlp.Disabled (v1alpha1) is renamed to input.otlp.Enabled (v1beta1) and its logic is inverted. +// - output.otlp.protocol is now of type enum in v1beta1 instead of string in v1alpha1. +// - output.otlp.TLS struct got renamed + // Remove invalid namespace names from NamespaceSelector slices (include/exclude) func sanitizeNamespaceNames(names []string) []string { var valid []string diff --git a/apis/telemetry/v1alpha1/tracepipeline_types.go b/apis/telemetry/v1alpha1/tracepipeline_types.go index 2314e9cb10..8202838ac6 100644 --- a/apis/telemetry/v1alpha1/tracepipeline_types.go +++ b/apis/telemetry/v1alpha1/tracepipeline_types.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1alpha1 import ( @@ -65,7 +49,7 @@ type TracePipelineSpec struct { // +kubebuilder:validation:Optional Transforms []TransformSpec `json:"transform,omitempty"` - // Filters specifies a list of filters to apply to telemetry data. + // Filter specifies a list of filters to apply to telemetry data. // +kubebuilder:validation:Optional Filters []FilterSpec `json:"filter,omitempty"` } diff --git a/apis/telemetry/v1beta1/groupversion_info.go b/apis/telemetry/v1beta1/groupversion_info.go index 4845656b74..7429b85e23 100644 --- a/apis/telemetry/v1beta1/groupversion_info.go +++ b/apis/telemetry/v1beta1/groupversion_info.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1beta1 contains API Schema definitions for the telemetry v1beta1 API group // +kubebuilder:object:generate=true // +groupName=telemetry.kyma-project.io diff --git a/apis/telemetry/v1beta1/logpipeline_types.go b/apis/telemetry/v1beta1/logpipeline_types.go index db00b04cb8..8df21b4251 100644 --- a/apis/telemetry/v1beta1/logpipeline_types.go +++ b/apis/telemetry/v1beta1/logpipeline_types.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1beta1 import ( diff --git a/apis/telemetry/v1beta1/metricpipeline_types.go b/apis/telemetry/v1beta1/metricpipeline_types.go index 77ba1d49b8..e8bdb8ef96 100644 --- a/apis/telemetry/v1beta1/metricpipeline_types.go +++ b/apis/telemetry/v1beta1/metricpipeline_types.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1beta1 import ( diff --git a/apis/telemetry/v1beta1/tracepipeline_types.go b/apis/telemetry/v1beta1/tracepipeline_types.go index 82e20f658a..26d19be857 100644 --- a/apis/telemetry/v1beta1/tracepipeline_types.go +++ b/apis/telemetry/v1beta1/tracepipeline_types.go @@ -1,19 +1,3 @@ -/* -Copyright 2021. - -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 v1beta1 import ( @@ -68,7 +52,7 @@ type TracePipelineSpec struct { // Filter specifies a list of filters to apply to telemetry data. // +kubebuilder:validation:Optional - Filter []FilterSpec `json:"filter,omitempty"` + Filters []FilterSpec `json:"filter,omitempty"` } // TracePipelineOutput defines the output configuration section. diff --git a/apis/telemetry/v1beta1/zz_generated.deepcopy.go b/apis/telemetry/v1beta1/zz_generated.deepcopy.go index 8f904d5105..c156e7ff10 100644 --- a/apis/telemetry/v1beta1/zz_generated.deepcopy.go +++ b/apis/telemetry/v1beta1/zz_generated.deepcopy.go @@ -1020,8 +1020,8 @@ func (in *TracePipelineSpec) DeepCopyInto(out *TracePipelineSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.Filter != nil { - in, out := &in.Filter, &out.Filter + if in.Filters != nil { + in, out := &in.Filters, &out.Filters *out = make([]FilterSpec, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml index 8a58db785f..be49be477b 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_metricpipelines.yaml @@ -65,7 +65,7 @@ spec: description: Spec defines the desired characteristics of MetricPipeline. properties: filter: - description: Filters specifies a list of filters to apply to telemetry + description: Filter specifies a list of filters to apply to telemetry data. items: description: FilterSpec defines a filter to apply to telemetry data. diff --git a/helm/charts/experimental/templates/telemetry.kyma-project.io_tracepipelines.yaml b/helm/charts/experimental/templates/telemetry.kyma-project.io_tracepipelines.yaml index 8c4694cd28..0642bd2e90 100644 --- a/helm/charts/experimental/templates/telemetry.kyma-project.io_tracepipelines.yaml +++ b/helm/charts/experimental/templates/telemetry.kyma-project.io_tracepipelines.yaml @@ -62,7 +62,7 @@ spec: description: Spec defines the desired state of TracePipeline properties: filter: - description: Filters specifies a list of filters to apply to telemetry + description: Filter specifies a list of filters to apply to telemetry data. items: description: FilterSpec defines a filter to apply to telemetry data. From 090a90e28f02428c6ca65abc69435772b16b3c6b Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Thu, 30 Oct 2025 17:20:50 +0100 Subject: [PATCH 23/27] review --- main.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/main.go b/main.go index 478e22ecf0..ffa842cddd 100644 --- a/main.go +++ b/main.go @@ -409,20 +409,6 @@ func setupLogPipelineController(mgr manager.Manager, reconcileTriggerChan <-chan Complete(); err != nil { return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) } - - setupLog.Info("Registering conversion webhooks for MetricPipelines") - - if err := ctrl.NewWebhookManagedBy(mgr). - For(&telemetryv1alpha1.MetricPipeline{}). - Complete(); err != nil { - return fmt.Errorf("failed to create v1alpha1 conversion webhook: %w", err) - } - - if err := ctrl.NewWebhookManagedBy(mgr). - For(&telemetryv1beta1.MetricPipeline{}). - Complete(); err != nil { - return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) - } } setupLog.Info("Setting up logpipeline controller") @@ -520,6 +506,20 @@ func setupMetricPipelineController(mgr manager.Manager, reconcileTriggerChan <-c return fmt.Errorf("failed to setup metricpipeline controller: %w", err) } + setupLog.Info("Registering conversion webhooks for MetricPipelines") + + if err := ctrl.NewWebhookManagedBy(mgr). + For(&telemetryv1alpha1.MetricPipeline{}). + Complete(); err != nil { + return fmt.Errorf("failed to create v1alpha1 conversion webhook: %w", err) + } + + if err := ctrl.NewWebhookManagedBy(mgr). + For(&telemetryv1beta1.MetricPipeline{}). + Complete(); err != nil { + return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) + } + return nil } From 2ec2ecdad72aa5941eaa52341726ccc9db70c1b9 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Thu, 30 Oct 2025 17:24:51 +0100 Subject: [PATCH 24/27] review feedback --- main.go | 62 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/main.go b/main.go index ffa842cddd..2e133cdff6 100644 --- a/main.go +++ b/main.go @@ -205,6 +205,10 @@ func setupControllersAndWebhooks(mgr manager.Manager) error { return fmt.Errorf("failed to setup admission webhooks: %w", err) } + if err := setupConversionWebhooks(mgr); err != nil { + return fmt.Errorf("failed to setup conversion webhooks: %w", err) + } + mgr.GetWebhookServer().Register("/api/v2/alerts", selfmonitorwebhook.NewHandler( mgr.GetClient(), selfmonitorwebhook.WithTracePipelineSubscriber(TracePipelineReconcile), @@ -394,23 +398,6 @@ func getImagesFromEnv() error { } func setupLogPipelineController(mgr manager.Manager, reconcileTriggerChan <-chan event.GenericEvent) error { - if featureflags.IsEnabled(featureflags.V1Beta1) { - setupLog.Info("Registering conversion webhooks for LogPipelines") - utilruntime.Must(telemetryv1beta1.AddToScheme(scheme)) - - if err := ctrl.NewWebhookManagedBy(mgr). - For(&telemetryv1alpha1.LogPipeline{}). - Complete(); err != nil { - return fmt.Errorf("failed to create v1alpha1 conversion webhook: %w", err) - } - - if err := ctrl.NewWebhookManagedBy(mgr). - For(&telemetryv1beta1.LogPipeline{}). - Complete(); err != nil { - return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) - } - } - setupLog.Info("Setting up logpipeline controller") logPipelineController, err := telemetrycontrollers.NewLogPipelineController( @@ -506,18 +493,39 @@ func setupMetricPipelineController(mgr manager.Manager, reconcileTriggerChan <-c return fmt.Errorf("failed to setup metricpipeline controller: %w", err) } - setupLog.Info("Registering conversion webhooks for MetricPipelines") + return nil +} - if err := ctrl.NewWebhookManagedBy(mgr). - For(&telemetryv1alpha1.MetricPipeline{}). - Complete(); err != nil { - return fmt.Errorf("failed to create v1alpha1 conversion webhook: %w", err) - } +func setupConversionWebhooks(mgr manager.Manager) error { + if featureflags.IsEnabled(featureflags.V1Beta1) { + setupLog.Info("Registering conversion webhooks for LogPipelines") + utilruntime.Must(telemetryv1beta1.AddToScheme(scheme)) + + if err := ctrl.NewWebhookManagedBy(mgr). + For(&telemetryv1alpha1.LogPipeline{}). + Complete(); err != nil { + return fmt.Errorf("failed to create v1alpha1 conversion webhook: %w", err) + } - if err := ctrl.NewWebhookManagedBy(mgr). - For(&telemetryv1beta1.MetricPipeline{}). - Complete(); err != nil { - return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) + if err := ctrl.NewWebhookManagedBy(mgr). + For(&telemetryv1beta1.LogPipeline{}). + Complete(); err != nil { + return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) + } + + setupLog.Info("Registering conversion webhooks for MetricPipelines") + + if err := ctrl.NewWebhookManagedBy(mgr). + For(&telemetryv1alpha1.MetricPipeline{}). + Complete(); err != nil { + return fmt.Errorf("failed to create v1alpha1 conversion webhook: %w", err) + } + + if err := ctrl.NewWebhookManagedBy(mgr). + For(&telemetryv1beta1.MetricPipeline{}). + Complete(); err != nil { + return fmt.Errorf("failed to create v1beta1 conversion webhook: %w", err) + } } return nil From 339efc1427f0e574965120f50173df335afe9631 Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Fri, 31 Oct 2025 16:46:29 +0100 Subject: [PATCH 25/27] fix test failure --- main.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 2e133cdff6..6e379958f0 100644 --- a/main.go +++ b/main.go @@ -201,14 +201,14 @@ func setupControllersAndWebhooks(mgr manager.Manager) error { return fmt.Errorf("failed to enable webhook server: %w", err) } - if err := setupAdmissionsWebhooks(mgr); err != nil { - return fmt.Errorf("failed to setup admission webhooks: %w", err) - } - if err := setupConversionWebhooks(mgr); err != nil { return fmt.Errorf("failed to setup conversion webhooks: %w", err) } + if err := setupAdmissionsWebhooks(mgr); err != nil { + return fmt.Errorf("failed to setup admission webhooks: %w", err) + } + mgr.GetWebhookServer().Register("/api/v2/alerts", selfmonitorwebhook.NewHandler( mgr.GetClient(), selfmonitorwebhook.WithTracePipelineSubscriber(TracePipelineReconcile), From 5f6f2992beb2adb14b34e32428506d3797b54deb Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Mon, 3 Nov 2025 15:28:34 +0100 Subject: [PATCH 26/27] fix --- apis/telemetry/v1alpha1/logpipeline_conversion.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apis/telemetry/v1alpha1/logpipeline_conversion.go b/apis/telemetry/v1alpha1/logpipeline_conversion.go index e07ff12aa1..5b614db1a6 100644 --- a/apis/telemetry/v1alpha1/logpipeline_conversion.go +++ b/apis/telemetry/v1alpha1/logpipeline_conversion.go @@ -239,7 +239,7 @@ func convertRuntimeToAlpha(runtime *telemetryv1beta1.LogPipelineRuntimeInput) *L KeepOriginalBody: runtime.KeepOriginalBody, } - if runtime.Namespaces != nil { + if runtime.Namespaces != nil && (len(runtime.Namespaces.Include) > 0 || len(runtime.Namespaces.Exclude) > 0) { application.Namespaces = LogPipelineNamespaceSelector{ Include: append([]string{}, runtime.Namespaces.Include...), Exclude: append([]string{}, runtime.Namespaces.Exclude...), @@ -247,7 +247,7 @@ func convertRuntimeToAlpha(runtime *telemetryv1beta1.LogPipelineRuntimeInput) *L } } - if runtime.Containers != nil { + if runtime.Containers != nil && (len(runtime.Containers.Include) > 0 || len(runtime.Containers.Exclude) > 0) { application.Containers = LogPipelineContainerSelector{ Include: append([]string{}, runtime.Containers.Include...), Exclude: append([]string{}, runtime.Containers.Exclude...), From 53634382717dc68c1f8939fa187a3df6d1ca894d Mon Sep 17 00:00:00 2001 From: Andreas Thaler Date: Tue, 4 Nov 2025 15:22:59 +0100 Subject: [PATCH 27/27] fix --- apis/telemetry/v1beta1/logpipeline_types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apis/telemetry/v1beta1/logpipeline_types.go b/apis/telemetry/v1beta1/logpipeline_types.go index fe6e88a480..19cc0827ac 100644 --- a/apis/telemetry/v1beta1/logpipeline_types.go +++ b/apis/telemetry/v1beta1/logpipeline_types.go @@ -100,10 +100,10 @@ type LogPipelineRuntimeInput struct { Enabled *bool `json:"enabled,omitempty"` // Namespaces describes whether application logs from specific namespaces are selected. The options are mutually exclusive. By default, all namespaces except the system namespaces are enabled. To enable all namespaces including system namespaces, use an empty struct notation. // +kubebuilder:validation:Optional - Namespaces *NamespaceSelector `json:"namespaces"` + Namespaces *NamespaceSelector `json:"namespaces,omitempty"` // Containers describes whether application logs from specific containers are selected. The options are mutually exclusive. // +kubebuilder:validation:Optional - Containers *LogPipelineContainerSelector `json:"containers"` + Containers *LogPipelineContainerSelector `json:"containers,omitempty"` // KeepAnnotations defines whether to keep all Kubernetes annotations. The default is `false`. Only available when using an output of type `http` and `custom`. // +kubebuilder:validation:Optional KeepAnnotations *bool `json:"keepAnnotations,omitempty"`