diff --git a/pkg/collector/upgrade/testdata/v0_61_0-invalid.yaml b/pkg/collector/upgrade/testdata/v0_61_0-invalid.yaml new file mode 100644 index 0000000000..e04bc249a2 --- /dev/null +++ b/pkg/collector/upgrade/testdata/v0_61_0-invalid.yaml @@ -0,0 +1,8 @@ +--- +receivers: + jaeger: + protocols: + grpc: + remote_sampling: + strategy_file: "/etc/strategy.json" + strategy_file_reload_interval: 10s diff --git a/pkg/collector/upgrade/testdata/v0_61_0-valid.yaml b/pkg/collector/upgrade/testdata/v0_61_0-valid.yaml new file mode 100644 index 0000000000..2dc25ca4a1 --- /dev/null +++ b/pkg/collector/upgrade/testdata/v0_61_0-valid.yaml @@ -0,0 +1,5 @@ +--- +receivers: + jaeger: + protocols: + grpc: diff --git a/pkg/collector/upgrade/upgrade.go b/pkg/collector/upgrade/upgrade.go index 93123a7f00..7d6dae3bf2 100644 --- a/pkg/collector/upgrade/upgrade.go +++ b/pkg/collector/upgrade/upgrade.go @@ -61,7 +61,9 @@ func (u VersionUpgrade) ManagedInstances(ctx context.Context) error { } upgraded, err := u.ManagedInstance(ctx, original) if err != nil { - // nothing to do at this level, just go to the next instance + const msg = "automated update not possible. Configuration must be corrected manually and CR instance must be re-created." + itemLogger.Info(msg) + u.Recorder.Event(&original, "Error", "Upgrade", msg) continue } diff --git a/pkg/collector/upgrade/v0_61_0.go b/pkg/collector/upgrade/v0_61_0.go new file mode 100644 index 0000000000..dff6365a63 --- /dev/null +++ b/pkg/collector/upgrade/v0_61_0.go @@ -0,0 +1,69 @@ +// Copyright The OpenTelemetry Authors +// +// 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 upgrade + +import ( + "errors" + "fmt" + "strings" + + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/pkg/collector/adapters" +) + +func upgrade0_61_0(u VersionUpgrade, otelcol *v1alpha1.OpenTelemetryCollector) (*v1alpha1.OpenTelemetryCollector, error) { + if len(otelcol.Spec.Config) == 0 { + return otelcol, nil + } + + otelCfg, err := adapters.ConfigFromString(otelcol.Spec.Config) + if err != nil { + return otelcol, fmt.Errorf("couldn't upgrade to v0.61.0, failed to parse configuration: %w", err) + } + + // Search for removed Jaeger remote sampling settings. (https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/14163) + receiversConfig, ok := otelCfg["receivers"].(map[any]any) + if !ok { + // In case there is no extensions config. + return otelcol, nil + } + + for key, rc := range receiversConfig { + k, ok := key.(string) + if !ok { + continue + } + cfg, ok := rc.(map[any]any) + // check if jaeger is configured + if !ok || !strings.HasPrefix(k, "jaeger") { + continue + } + + // check if remote sampling settings exit + if _, ok := cfg["remote_sampling"]; !ok { + continue + } + + const issueID = "https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/14707" + errStr := fmt.Sprintf( + "jaegerremotesampling is no longer available as receiver configuration. "+ + "Please use the extension instead with a different remote sampling port. See: %s", + issueID, + ) + u.Recorder.Event(otelcol, "Error", "Upgrade", errStr) + return nil, errors.New(errStr) + } + return otelcol, nil +} diff --git a/pkg/collector/upgrade/v0_61_0_test.go b/pkg/collector/upgrade/v0_61_0_test.go new file mode 100644 index 0000000000..5c43aa32b4 --- /dev/null +++ b/pkg/collector/upgrade/v0_61_0_test.go @@ -0,0 +1,86 @@ +// Copyright The OpenTelemetry Authors +// +// 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 upgrade_test + +import ( + "context" + _ "embed" + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/record" + + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/internal/version" + "github.com/open-telemetry/opentelemetry-operator/pkg/collector/upgrade" +) + +var ( + //go:embed testdata/v0_61_0-valid.yaml + valid string + //go:embed testdata/v0_61_0-invalid.yaml + invalid string +) + +func Test0_61_0Upgrade(t *testing.T) { + + collectorInstance := v1alpha1.OpenTelemetryCollector{ + TypeMeta: metav1.TypeMeta{ + Kind: "OpenTelemetryCollector", + APIVersion: "v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "otel-my-instance", + Namespace: "somewhere", + }, + Spec: v1alpha1.OpenTelemetryCollectorSpec{}, + } + + tt := []struct { + name string + config string + expectErr bool + }{ + { + name: "no remote sampling config", // valid + config: valid, + expectErr: false, + }, + { + name: "has remote sampling config", // invalid + config: invalid, + expectErr: true, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + collectorInstance.Spec.Config = tc.config + collectorInstance.Status.Version = "0.60.0" + + versionUpgrade := &upgrade.VersionUpgrade{ + Log: logger, + Version: version.Get(), + Client: k8sClient, + Recorder: record.NewFakeRecorder(upgrade.RecordBufferSize), + } + + _, err := versionUpgrade.ManagedInstance(context.Background(), collectorInstance) + if (err != nil) != tc.expectErr { + t.Errorf("expect err: %t but got: %v", tc.expectErr, err) + } + }) + } +} diff --git a/pkg/collector/upgrade/versions.go b/pkg/collector/upgrade/versions.go index a311cf2ee1..ae0870f044 100644 --- a/pkg/collector/upgrade/versions.go +++ b/pkg/collector/upgrade/versions.go @@ -81,6 +81,10 @@ var ( Version: *semver.MustParse("0.57.2"), upgrade: upgrade0_57_2, }, + { + Version: *semver.MustParse("0.61.0"), + upgrade: upgrade0_61_0, + }, } // Latest represents the latest version that we need to upgrade. This is not necessarily the latest known version.