From c9508fe58aadc551090935356f27e49aa3604414 Mon Sep 17 00:00:00 2001
From: Pavol Loffay
Date: Tue, 5 Mar 2024 19:25:52 +0100
Subject: [PATCH] Add conversion go APIs (#2711)
* Add conversion go APIs
Signed-off-by: Pavol Loffay
* Fix
Signed-off-by: Pavol Loffay
* Fix
Signed-off-by: Pavol Loffay
* Fix
Signed-off-by: Pavol Loffay
---------
Signed-off-by: Pavol Loffay
---
apis/v1alpha1/convert.go | 43 ++++++++++-
apis/v1alpha1/convert_test.go | 74 ++++++++++++++++++-
apis/v1beta1/opentelemetrycollector_types.go | 2 +
.../opentelemetrycollector_controller.go | 4 +-
pkg/sidecar/pod_test.go | 42 ++++++-----
pkg/sidecar/podmutator.go | 4 +-
6 files changed, 142 insertions(+), 27 deletions(-)
diff --git a/apis/v1alpha1/convert.go b/apis/v1alpha1/convert.go
index 792e891e30..9f7e01fb78 100644
--- a/apis/v1alpha1/convert.go
+++ b/apis/v1alpha1/convert.go
@@ -16,15 +16,53 @@ package v1alpha1
import (
"errors"
+ "fmt"
"gopkg.in/yaml.v3"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "sigs.k8s.io/controller-runtime/pkg/conversion"
"github.com/open-telemetry/opentelemetry-operator/apis/v1beta1"
)
-func Tov1beta1(in OpenTelemetryCollector) (v1beta1.OpenTelemetryCollector, error) {
+var _ conversion.Convertible = &OpenTelemetryCollector{}
+
+func (src *OpenTelemetryCollector) ConvertTo(dstRaw conversion.Hub) error {
+ switch t := dstRaw.(type) {
+ case *v1beta1.OpenTelemetryCollector:
+ dst := dstRaw.(*v1beta1.OpenTelemetryCollector)
+ convertedSrc, err := tov1beta1(*src)
+ if err != nil {
+ return fmt.Errorf("failed to convert to v1beta1: %w", err)
+ }
+ dst.ObjectMeta = convertedSrc.ObjectMeta
+ dst.Spec = convertedSrc.Spec
+ dst.Status = convertedSrc.Status
+ default:
+ return fmt.Errorf("unsupported type %v", t)
+ }
+ return nil
+}
+
+func (dst *OpenTelemetryCollector) ConvertFrom(srcRaw conversion.Hub) error {
+ switch t := srcRaw.(type) {
+ case *v1beta1.OpenTelemetryCollector:
+ src := srcRaw.(*v1beta1.OpenTelemetryCollector)
+ srcConverted, err := tov1alpha1(*src)
+ if err != nil {
+ return fmt.Errorf("failed to convert to v1alpha1: %w", err)
+ }
+ dst.ObjectMeta = srcConverted.ObjectMeta
+ dst.Spec = srcConverted.Spec
+ dst.Status = srcConverted.Status
+ default:
+ return fmt.Errorf("unsupported type %v", t)
+ }
+ return nil
+}
+
+func tov1beta1(in OpenTelemetryCollector) (v1beta1.OpenTelemetryCollector, error) {
copy := in.DeepCopy()
cfg := &v1beta1.Config{}
if err := yaml.Unmarshal([]byte(copy.Spec.Config), cfg); err != nil {
@@ -120,6 +158,7 @@ func tov1beta1TA(in OpenTelemetryTargetAllocator) v1beta1.TargetAllocatorEmbedde
PrometheusCR: v1beta1.TargetAllocatorPrometheusCR{
Enabled: in.PrometheusCR.Enabled,
ScrapeInterval: in.PrometheusCR.ScrapeInterval,
+ // prometheus_cr.pod_monitor_selector shouldn't be nil when selector is empty
PodMonitorSelector: &metav1.LabelSelector{
MatchLabels: in.PrometheusCR.PodMonitorSelector,
},
@@ -236,7 +275,7 @@ func tov1alpha1(in v1beta1.OpenTelemetryCollector) (*OpenTelemetryCollector, err
SecurityContext: copy.Spec.SecurityContext,
PodSecurityContext: copy.Spec.PodSecurityContext,
PodAnnotations: copy.Spec.PodAnnotations,
- TargetAllocator: tov1alpha1TA(in.Spec.TargetAllocator),
+ TargetAllocator: tov1alpha1TA(copy.Spec.TargetAllocator),
Mode: Mode(copy.Spec.Mode),
ServiceAccount: copy.Spec.ServiceAccount,
Image: copy.Spec.Image,
diff --git a/apis/v1alpha1/convert_test.go b/apis/v1alpha1/convert_test.go
index ad248d278b..f7952702ce 100644
--- a/apis/v1alpha1/convert_test.go
+++ b/apis/v1alpha1/convert_test.go
@@ -62,7 +62,7 @@ func Test_tov1beta1_config(t *testing.T) {
},
}
- cfgV2, err := Tov1beta1(cfgV1)
+ cfgV2, err := tov1beta1(cfgV1)
assert.Nil(t, err)
assert.NotNil(t, cfgV2)
assert.Equal(t, cfgV1.Spec.Args, cfgV2.Spec.Args)
@@ -79,7 +79,7 @@ func Test_tov1beta1_config(t *testing.T) {
},
}
- _, err := Tov1beta1(cfgV1)
+ _, err := tov1beta1(cfgV1)
assert.ErrorContains(t, err, "could not convert config json to v1beta1.Config")
})
}
@@ -310,7 +310,7 @@ func Test_tov1beta1AndBack(t *testing.T) {
},
}
- colbeta1, err := Tov1beta1(*colalpha1)
+ colbeta1, err := tov1beta1(*colalpha1)
require.NoError(t, err)
colalpha1Converted, err := tov1alpha1(colbeta1)
require.NoError(t, err)
@@ -421,3 +421,71 @@ func createTA() OpenTelemetryTargetAllocator {
},
}
}
+
+func TestConvertTo(t *testing.T) {
+ col := OpenTelemetryCollector{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "otel",
+ },
+ Spec: OpenTelemetryCollectorSpec{
+ ServiceAccount: "otelcol",
+ },
+ Status: OpenTelemetryCollectorStatus{
+ Image: "otel/col",
+ },
+ }
+ colbeta1 := v1beta1.OpenTelemetryCollector{}
+ err := col.ConvertTo(&colbeta1)
+ require.NoError(t, err)
+ assert.Equal(t, v1beta1.OpenTelemetryCollector{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "otel",
+ },
+ Spec: v1beta1.OpenTelemetryCollectorSpec{
+ OpenTelemetryCommonFields: v1beta1.OpenTelemetryCommonFields{
+ ServiceAccount: "otelcol",
+ },
+ TargetAllocator: v1beta1.TargetAllocatorEmbedded{
+ PrometheusCR: v1beta1.TargetAllocatorPrometheusCR{
+ PodMonitorSelector: &metav1.LabelSelector{},
+ ServiceMonitorSelector: &metav1.LabelSelector{},
+ },
+ },
+ },
+ Status: v1beta1.OpenTelemetryCollectorStatus{
+ Image: "otel/col",
+ },
+ }, colbeta1)
+}
+
+func TestConvertFrom(t *testing.T) {
+ colbeta1 := v1beta1.OpenTelemetryCollector{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "otel",
+ },
+ Spec: v1beta1.OpenTelemetryCollectorSpec{
+ OpenTelemetryCommonFields: v1beta1.OpenTelemetryCommonFields{
+ ServiceAccount: "otelcol",
+ },
+ },
+ Status: v1beta1.OpenTelemetryCollectorStatus{
+ Image: "otel/col",
+ },
+ }
+ col := OpenTelemetryCollector{}
+ err := col.ConvertFrom(&colbeta1)
+ require.NoError(t, err)
+ // set config to empty. The v1beta1 marshals config with empty receivers, exporters..
+ col.Spec.Config = ""
+ assert.Equal(t, OpenTelemetryCollector{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "otel",
+ },
+ Spec: OpenTelemetryCollectorSpec{
+ ServiceAccount: "otelcol",
+ },
+ Status: OpenTelemetryCollectorStatus{
+ Image: "otel/col",
+ },
+ }, col)
+}
diff --git a/apis/v1beta1/opentelemetrycollector_types.go b/apis/v1beta1/opentelemetrycollector_types.go
index 246bdbb0d5..6982cabab9 100644
--- a/apis/v1beta1/opentelemetrycollector_types.go
+++ b/apis/v1beta1/opentelemetrycollector_types.go
@@ -334,6 +334,8 @@ type OpenTelemetryCollector struct {
Status OpenTelemetryCollectorStatus `json:"status,omitempty"`
}
+func (*OpenTelemetryCollector) Hub() {}
+
//+kubebuilder:object:root=true
// OpenTelemetryCollectorList contains a list of OpenTelemetryCollector.
diff --git a/controllers/opentelemetrycollector_controller.go b/controllers/opentelemetrycollector_controller.go
index 8ce028ff7e..309da9aa91 100644
--- a/controllers/opentelemetrycollector_controller.go
+++ b/controllers/opentelemetrycollector_controller.go
@@ -37,6 +37,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
+ "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1"
"github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift"
"github.com/open-telemetry/opentelemetry-operator/internal/config"
"github.com/open-telemetry/opentelemetry-operator/internal/manifests"
@@ -130,7 +131,8 @@ func (r *OpenTelemetryCollectorReconciler) findOtelOwnedObjects(ctx context.Cont
}
func (r *OpenTelemetryCollectorReconciler) getParams(instance v1alpha1.OpenTelemetryCollector) (manifests.Params, error) {
- otelCol, err := v1alpha1.Tov1beta1(instance)
+ otelCol := v1beta1.OpenTelemetryCollector{}
+ err := instance.ConvertTo(&otelCol)
if err != nil {
return manifests.Params{}, err
}
diff --git a/pkg/sidecar/pod_test.go b/pkg/sidecar/pod_test.go
index 044437309b..a15548c62d 100644
--- a/pkg/sidecar/pod_test.go
+++ b/pkg/sidecar/pod_test.go
@@ -47,33 +47,35 @@ func TestAddSidecarWhenNoSidecarExists(t *testing.T) {
Volumes: []corev1.Volume{{}},
},
}
- otelcol, err := v1alpha1.Tov1beta1(
- v1alpha1.OpenTelemetryCollector{
- ObjectMeta: metav1.ObjectMeta{
- Name: "otelcol-sample-with-a-name-that-is-longer-than-sixty-three-characters",
- Namespace: "some-app",
- },
- Spec: v1alpha1.OpenTelemetryCollectorSpec{
- Ports: []corev1.ServicePort{
- {
- Name: "metrics",
- Port: 8888,
- Protocol: corev1.ProtocolTCP,
- },
+
+ v1alpha1Col := v1alpha1.OpenTelemetryCollector{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "otelcol-sample-with-a-name-that-is-longer-than-sixty-three-characters",
+ Namespace: "some-app",
+ },
+ Spec: v1alpha1.OpenTelemetryCollectorSpec{
+ Ports: []corev1.ServicePort{
+ {
+ Name: "metrics",
+ Port: 8888,
+ Protocol: corev1.ProtocolTCP,
},
- InitContainers: []corev1.Container{
- {
- Name: "test",
- },
+ },
+ InitContainers: []corev1.Container{
+ {
+ Name: "test",
},
- Config: `
+ },
+ Config: `
receivers:
exporters:
processors:
`,
- },
},
- )
+ }
+
+ otelcol := v1beta1.OpenTelemetryCollector{}
+ err := v1alpha1Col.ConvertTo(&otelcol)
require.NoError(t, err)
otelcolYaml, err := otelcol.Spec.Config.Yaml()
require.NoError(t, err)
diff --git a/pkg/sidecar/podmutator.go b/pkg/sidecar/podmutator.go
index b489aec7f8..635c668463 100644
--- a/pkg/sidecar/podmutator.go
+++ b/pkg/sidecar/podmutator.go
@@ -27,6 +27,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
+ "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1"
"github.com/open-telemetry/opentelemetry-operator/internal/config"
"github.com/open-telemetry/opentelemetry-operator/internal/webhook/podmutation"
)
@@ -97,7 +98,8 @@ func (p *sidecarPodMutator) Mutate(ctx context.Context, ns corev1.Namespace, pod
// we should add the sidecar.
logger.V(1).Info("injecting sidecar into pod", "otelcol-namespace", otelcol.Namespace, "otelcol-name", otelcol.Name)
- otc, err := v1alpha1.Tov1beta1(otelcol)
+ otc := v1beta1.OpenTelemetryCollector{}
+ err = otelcol.ConvertTo(&otc)
if err != nil {
return corev1.Pod{}, err
}