diff --git a/internal/api/convert/v1alpha.go b/apis/v1alpha1/convert.go similarity index 94% rename from internal/api/convert/v1alpha.go rename to apis/v1alpha1/convert.go index 50a4cc57bc..9f8fbe0e37 100644 --- a/internal/api/convert/v1alpha.go +++ b/apis/v1alpha1/convert.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package convert +package v1alpha1 import ( "errors" @@ -20,11 +20,10 @@ import ( "gopkg.in/yaml.v3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" ) -func V1Alpha1to2(in v1alpha1.OpenTelemetryCollector) (v1beta1.OpenTelemetryCollector, error) { +func Tov1beta1(in OpenTelemetryCollector) (v1beta1.OpenTelemetryCollector, error) { copy := in.DeepCopy() out := v1beta1.OpenTelemetryCollector{ TypeMeta: copy.TypeMeta, @@ -125,7 +124,12 @@ func V1Alpha1to2(in v1alpha1.OpenTelemetryCollector) (v1beta1.OpenTelemetryColle out.Spec.Observability.Metrics.EnableMetrics = copy.Spec.Observability.Metrics.EnableMetrics - out.Spec.ConfigMaps = copy.Spec.ConfigMaps + for _, cm := range copy.Spec.ConfigMaps { + out.Spec.ConfigMaps = append(out.Spec.ConfigMaps, v1beta1.ConfigMapsSpec{ + Name: cm.Name, + MountPath: cm.MountPath, + }) + } out.Spec.DaemonSetUpdateStrategy = copy.Spec.UpdateStrategy out.Spec.DeploymentUpdateStrategy.Type = copy.Spec.DeploymentUpdateStrategy.Type out.Spec.DeploymentUpdateStrategy.RollingUpdate = copy.Spec.DeploymentUpdateStrategy.RollingUpdate @@ -133,7 +137,7 @@ func V1Alpha1to2(in v1alpha1.OpenTelemetryCollector) (v1beta1.OpenTelemetryColle return out, nil } -func TargetAllocatorEmbedded(in v1alpha1.OpenTelemetryTargetAllocator) v1beta1.TargetAllocatorEmbedded { +func TargetAllocatorEmbedded(in OpenTelemetryTargetAllocator) v1beta1.TargetAllocatorEmbedded { out := v1beta1.TargetAllocatorEmbedded{} out.Replicas = in.Replicas out.NodeSelector = in.NodeSelector @@ -151,8 +155,8 @@ func TargetAllocatorEmbedded(in v1alpha1.OpenTelemetryTargetAllocator) v1beta1.T out.TopologySpreadConstraints = in.TopologySpreadConstraints out.Tolerations = in.Tolerations out.Env = in.Env - out.Observability = v1alpha1.ObservabilitySpec{ - Metrics: v1alpha1.MetricsConfigSpec{ + out.Observability = v1beta1.ObservabilitySpec{ + Metrics: v1beta1.MetricsConfigSpec{ EnableMetrics: in.Observability.Metrics.EnableMetrics, }, } diff --git a/internal/api/convert/v1alpha_test.go b/apis/v1alpha1/convert_test.go similarity index 87% rename from internal/api/convert/v1alpha_test.go rename to apis/v1alpha1/convert_test.go index fb19862766..a63a32f79a 100644 --- a/internal/api/convert/v1alpha_test.go +++ b/apis/v1alpha1/convert_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package convert +package v1alpha1 import ( "testing" @@ -25,7 +25,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" ) @@ -49,8 +48,8 @@ service: processors: [resourcedetection] exporters: [otlp] ` - cfgV1 := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ + cfgV1 := OpenTelemetryCollector{ + Spec: OpenTelemetryCollectorSpec{ Config: config, Args: map[string]string{ "test": "something", @@ -58,7 +57,7 @@ service: }, } - cfgV2, err := V1Alpha1to2(cfgV1) + cfgV2, err := Tov1beta1(cfgV1) assert.Nil(t, err) assert.NotNil(t, cfgV2) assert.Equal(t, cfgV1.Spec.Args, cfgV2.Spec.Args) @@ -69,13 +68,13 @@ service: }) t.Run("invalid config", func(t *testing.T) { config := `!!!` - cfgV1 := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ + cfgV1 := OpenTelemetryCollector{ + Spec: OpenTelemetryCollectorSpec{ Config: config, }, } - _, err := V1Alpha1to2(cfgV1) + _, err := Tov1beta1(cfgV1) assert.ErrorContains(t, err, "could not convert config json to v1beta1.Config") }) } @@ -86,7 +85,7 @@ func Test_TargetAllocator(t *testing.T) { privileged := true runAsUser := int64(1337) runasGroup := int64(1338) - input := v1alpha1.OpenTelemetryTargetAllocator{ + input := OpenTelemetryTargetAllocator{ Replicas: &replicas, NodeSelector: map[string]string{"key": "value"}, Resources: v1.ResourceRequirements{ @@ -99,7 +98,7 @@ func Test_TargetAllocator(t *testing.T) { v1.ResourceMemory: resource.MustParse("128Mi"), }, }, - AllocationStrategy: v1alpha1.OpenTelemetryTargetAllocatorAllocationStrategyConsistentHashing, + AllocationStrategy: OpenTelemetryTargetAllocatorAllocationStrategyConsistentHashing, FilterStrategy: "relabel-config", ServiceAccount: "serviceAccountName", Image: "custom_image", @@ -121,7 +120,7 @@ func Test_TargetAllocator(t *testing.T) { }, }, }, - PrometheusCR: v1alpha1.OpenTelemetryTargetAllocatorPrometheusCR{ + PrometheusCR: OpenTelemetryTargetAllocatorPrometheusCR{ Enabled: true, ScrapeInterval: &metav1.Duration{Duration: time.Second}, PodMonitorSelector: map[string]string{"podmonitorkey": "podmonitorvalue"}, @@ -165,12 +164,12 @@ func Test_TargetAllocator(t *testing.T) { }, }, }, - Observability: v1alpha1.ObservabilitySpec{ - Metrics: v1alpha1.MetricsConfigSpec{ + Observability: ObservabilitySpec{ + Metrics: MetricsConfigSpec{ EnableMetrics: true, }, }, - PodDisruptionBudget: &v1alpha1.PodDisruptionBudgetSpec{ + PodDisruptionBudget: &PodDisruptionBudgetSpec{ MaxUnavailable: &intstr.IntOrString{ Type: intstr.Int, IntVal: 1, @@ -203,7 +202,12 @@ func Test_TargetAllocator(t *testing.T) { TopologySpreadConstraints: input.TopologySpreadConstraints, Tolerations: input.Tolerations, Env: input.Env, - Observability: input.Observability, + Observability: v1beta1.ObservabilitySpec{ + Metrics: v1beta1.MetricsConfigSpec{ + EnableMetrics: input.Observability.Metrics.EnableMetrics, + DisablePrometheusAnnotations: input.Observability.Metrics.DisablePrometheusAnnotations, + }, + }, PodDisruptionBudget: &v1beta1.PodDisruptionBudgetSpec{ MinAvailable: input.PodDisruptionBudget.MinAvailable, MaxUnavailable: input.PodDisruptionBudget.MaxUnavailable, diff --git a/apis/v1beta1/opentelemetrycollector_types.go b/apis/v1beta1/opentelemetrycollector_types.go index c93cc7af34..1428806502 100644 --- a/apis/v1beta1/opentelemetrycollector_types.go +++ b/apis/v1beta1/opentelemetrycollector_types.go @@ -21,8 +21,6 @@ import ( v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" ) // Probe defines the OpenTelemetry's pod probe config. Only Liveness probe is supported currently. @@ -148,12 +146,12 @@ type OpenTelemetryCollectorSpec struct { // +optional // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Observability" - Observability v1alpha1.ObservabilitySpec `json:"observability,omitempty"` + Observability ObservabilitySpec `json:"observability,omitempty"` // ConfigMaps is a list of ConfigMaps in the same namespace as the OpenTelemetryCollector // object, which shall be mounted into the Collector Pods. // Each ConfigMap will be added to the Collector's Deployments as a volume named `configmap-`. - ConfigMaps []v1alpha1.ConfigMapsSpec `json:"configmaps,omitempty"` + ConfigMaps []ConfigMapsSpec `json:"configmaps,omitempty"` // UpdateStrategy represents the strategy the operator will take replacing existing DaemonSet pods with new pods // https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec // This is only applicable to Daemonset mode. @@ -236,7 +234,7 @@ type TargetAllocatorEmbedded struct { // +optional // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Observability" - Observability v1alpha1.ObservabilitySpec `json:"observability,omitempty"` + Observability ObservabilitySpec `json:"observability,omitempty"` // PodDisruptionBudget specifies the pod disruption budget configuration to use // for the target allocator workload. // @@ -248,7 +246,7 @@ type TargetAllocatorEmbedded struct { type OpenTelemetryCollectorStatus struct { // Scale is the OpenTelemetryCollector's scale subresource status. // +optional - Scale v1alpha1.ScaleSubresourceStatus `json:"scale,omitempty"` + Scale ScaleSubresourceStatus `json:"scale,omitempty"` // Version of the managed OpenTelemetry Collector (operand) // +optional @@ -270,6 +268,59 @@ type OpenTelemetryCollectorStatus struct { Replicas int32 `json:"replicas,omitempty"` } +// ObservabilitySpec defines how telemetry data gets handled. +type ObservabilitySpec struct { + // Metrics defines the metrics configuration for operands. + // + // +optional + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Metrics Config" + Metrics MetricsConfigSpec `json:"metrics,omitempty"` +} + +// MetricsConfigSpec defines a metrics config. +type MetricsConfigSpec struct { + // EnableMetrics specifies if ServiceMonitor or PodMonitor(for sidecar mode) should be created for the service managed by the OpenTelemetry Operator. + // The operator.observability.prometheus feature gate must be enabled to use this feature. + // + // +optional + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Create ServiceMonitors for OpenTelemetry Collector" + EnableMetrics bool `json:"enableMetrics,omitempty"` + // DisablePrometheusAnnotations controls the automatic addition of default Prometheus annotations + // ('prometheus.io/scrape', 'prometheus.io/port', and 'prometheus.io/path') + // + // +optional + // +kubebuilder:validation:Optional + DisablePrometheusAnnotations bool `json:"disablePrometheusAnnotations,omitempty"` +} + +// ScaleSubresourceStatus defines the observed state of the OpenTelemetryCollector's +// scale subresource. +type ScaleSubresourceStatus struct { + // The selector used to match the OpenTelemetryCollector's + // deployment or statefulSet pods. + // +optional + Selector string `json:"selector,omitempty"` + + // The total number non-terminated pods targeted by this + // OpenTelemetryCollector's deployment or statefulSet. + // +optional + Replicas int32 `json:"replicas,omitempty"` + + // StatusReplicas is the number of pods targeted by this OpenTelemetryCollector's with a Ready Condition / + // Total number of non-terminated pods targeted by this OpenTelemetryCollector's (their labels match the selector). + // Deployment, Daemonset, StatefulSet. + // +optional + StatusReplicas string `json:"statusReplicas,omitempty"` +} + +type ConfigMapsSpec struct { + // Configmap defines name and path where the configMaps should be mounted. + Name string `json:"name"` + MountPath string `json:"mountpath"` +} + //+kubebuilder:object:root=true //+kubebuilder:subresource:status diff --git a/apis/v1beta1/zz_generated.deepcopy.go b/apis/v1beta1/zz_generated.deepcopy.go index f6b298811f..442bb72a57 100644 --- a/apis/v1beta1/zz_generated.deepcopy.go +++ b/apis/v1beta1/zz_generated.deepcopy.go @@ -20,7 +20,6 @@ package v1beta1 import ( - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "k8s.io/api/autoscaling/v2" "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" @@ -106,6 +105,21 @@ func (in *Config) DeepCopy() *Config { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigMapsSpec) DeepCopyInto(out *ConfigMapsSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapsSpec. +func (in *ConfigMapsSpec) DeepCopy() *ConfigMapsSpec { + if in == nil { + return nil + } + out := new(ConfigMapsSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Ingress) DeepCopyInto(out *Ingress) { *out = *in @@ -161,6 +175,37 @@ func (in *MetricSpec) DeepCopy() *MetricSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MetricsConfigSpec) DeepCopyInto(out *MetricsConfigSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsConfigSpec. +func (in *MetricsConfigSpec) DeepCopy() *MetricsConfigSpec { + if in == nil { + return nil + } + out := new(MetricsConfigSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObservabilitySpec) DeepCopyInto(out *ObservabilitySpec) { + *out = *in + out.Metrics = in.Metrics +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObservabilitySpec. +func (in *ObservabilitySpec) DeepCopy() *ObservabilitySpec { + if in == nil { + return nil + } + out := new(ObservabilitySpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenShiftRoute) DeepCopyInto(out *OpenShiftRoute) { *out = *in @@ -250,7 +295,7 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp out.Observability = in.Observability if in.ConfigMaps != nil { in, out := &in.ConfigMaps, &out.ConfigMaps - *out = make([]v1alpha1.ConfigMapsSpec, len(*in)) + *out = make([]ConfigMapsSpec, len(*in)) copy(*out, *in) } in.DaemonSetUpdateStrategy.DeepCopyInto(&out.DaemonSetUpdateStrategy) @@ -505,6 +550,21 @@ func (in *Probe) DeepCopy() *Probe { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ScaleSubresourceStatus) DeepCopyInto(out *ScaleSubresourceStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScaleSubresourceStatus. +func (in *ScaleSubresourceStatus) DeepCopy() *ScaleSubresourceStatus { + if in == nil { + return nil + } + out := new(ScaleSubresourceStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Service) DeepCopyInto(out *Service) { *out = *in diff --git a/controllers/builder_test.go b/controllers/builder_test.go index 4076ccd463..9586fea633 100644 --- a/controllers/builder_test.go +++ b/controllers/builder_test.go @@ -1551,8 +1551,8 @@ prometheus_cr: Enabled: true, }, FilterStrategy: "relabel-config", - Observability: v1alpha1.ObservabilitySpec{ - Metrics: v1alpha1.MetricsConfigSpec{ + Observability: v1beta1.ObservabilitySpec{ + Metrics: v1beta1.MetricsConfigSpec{ EnableMetrics: true, }, }, diff --git a/controllers/opentelemetrycollector_controller.go b/controllers/opentelemetrycollector_controller.go index ce7c3f9185..8ce028ff7e 100644 --- a/controllers/opentelemetrycollector_controller.go +++ b/controllers/opentelemetrycollector_controller.go @@ -37,7 +37,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "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" @@ -131,7 +130,7 @@ func (r *OpenTelemetryCollectorReconciler) findOtelOwnedObjects(ctx context.Cont } func (r *OpenTelemetryCollectorReconciler) getParams(instance v1alpha1.OpenTelemetryCollector) (manifests.Params, error) { - otelCol, err := convert.V1Alpha1to2(instance) + otelCol, err := v1alpha1.Tov1beta1(instance) if err != nil { return manifests.Params{}, err } diff --git a/internal/manifests/collector/annotations_test.go b/internal/manifests/collector/annotations_test.go index ec773f195a..d65bb41b27 100644 --- a/internal/manifests/collector/annotations_test.go +++ b/internal/manifests/collector/annotations_test.go @@ -21,7 +21,6 @@ import ( "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" ) @@ -70,8 +69,8 @@ func TestNonDefaultPodAnnotation(t *testing.T) { Namespace: "my-ns", }, Spec: v1beta1.OpenTelemetryCollectorSpec{ - Observability: v1alpha1.ObservabilitySpec{ - Metrics: v1alpha1.MetricsConfigSpec{ + Observability: v1beta1.ObservabilitySpec{ + Metrics: v1beta1.MetricsConfigSpec{ DisablePrometheusAnnotations: true, }, }, diff --git a/internal/manifests/collector/container_test.go b/internal/manifests/collector/container_test.go index de80f962c2..5dfe16be69 100644 --- a/internal/manifests/collector/container_test.go +++ b/internal/manifests/collector/container_test.go @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/api/resource" logf "sigs.k8s.io/controller-runtime/pkg/log" - "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/manifests/collector" @@ -417,7 +416,7 @@ func TestContainerCustomConfigMapsVolumes(t *testing.T) { // prepare otelcol := v1beta1.OpenTelemetryCollector{ Spec: v1beta1.OpenTelemetryCollectorSpec{ - ConfigMaps: []v1alpha1.ConfigMapsSpec{{ + ConfigMaps: []v1beta1.ConfigMapsSpec{{ Name: "test", MountPath: "/", }, { diff --git a/internal/manifests/collector/volume_test.go b/internal/manifests/collector/volume_test.go index 0101699ebf..06832e6314 100644 --- a/internal/manifests/collector/volume_test.go +++ b/internal/manifests/collector/volume_test.go @@ -20,7 +20,6 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" - "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/manifests/collector" @@ -69,7 +68,7 @@ func TestVolumeWithMoreConfigMaps(t *testing.T) { // prepare otelcol := v1beta1.OpenTelemetryCollector{ Spec: v1beta1.OpenTelemetryCollectorSpec{ - ConfigMaps: []v1alpha1.ConfigMapsSpec{{ + ConfigMaps: []v1beta1.ConfigMapsSpec{{ Name: "configmap-test", MountPath: "/", }, { diff --git a/pkg/sidecar/pod_test.go b/pkg/sidecar/pod_test.go index 920f3890fe..044437309b 100644 --- a/pkg/sidecar/pod_test.go +++ b/pkg/sidecar/pod_test.go @@ -25,7 +25,6 @@ import ( "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -48,7 +47,7 @@ func TestAddSidecarWhenNoSidecarExists(t *testing.T) { Volumes: []corev1.Volume{{}}, }, } - otelcol, err := convert.V1Alpha1to2( + otelcol, err := v1alpha1.Tov1beta1( v1alpha1.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "otelcol-sample-with-a-name-that-is-longer-than-sixty-three-characters", diff --git a/pkg/sidecar/podmutator.go b/pkg/sidecar/podmutator.go index d142d90353..b489aec7f8 100644 --- a/pkg/sidecar/podmutator.go +++ b/pkg/sidecar/podmutator.go @@ -27,7 +27,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/webhook/podmutation" ) @@ -98,7 +97,7 @@ 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 := convert.V1Alpha1to2(otelcol) + otc, err := v1alpha1.Tov1beta1(otelcol) if err != nil { return corev1.Pod{}, err }