diff --git a/internal/controllers/clusterextension_controller.go b/internal/controllers/clusterextension_controller.go index e03f865c21..6665d1fa7d 100644 --- a/internal/controllers/clusterextension_controller.go +++ b/internal/controllers/clusterextension_controller.go @@ -66,6 +66,7 @@ import ( "github.com/operator-framework/operator-controller/internal/catalogmetadata" catalogfilter "github.com/operator-framework/operator-controller/internal/catalogmetadata/filter" catalogsort "github.com/operator-framework/operator-controller/internal/catalogmetadata/sort" + "github.com/operator-framework/operator-controller/internal/packageerrors" rukpakapi "github.com/operator-framework/operator-controller/internal/rukpak/api" "github.com/operator-framework/operator-controller/internal/rukpak/handler" helmpredicate "github.com/operator-framework/operator-controller/internal/rukpak/helm-operator-plugins/predicate" @@ -610,17 +611,7 @@ func (r *ClusterExtensionReconciler) resolve(ctx context.Context, clusterExtensi resultSet := catalogfilter.Filter(allBundles, catalogfilter.And(predicates...)) if len(resultSet) == 0 { - var versionError, channelError, existingVersionError string - if versionRange != "" { - versionError = fmt.Sprintf(" matching version %q", versionRange) - } - if channelName != "" { - channelError = fmt.Sprintf(" in channel %q", channelName) - } - if installedVersion != "" { - existingVersionError = fmt.Sprintf(" which upgrades currently installed version %q", installedVersion) - } - return nil, fmt.Errorf("no package %q%s%s%s found", packageName, versionError, channelError, existingVersionError) + return nil, packageerrors.GenerateFullError(packageName, versionRange, channelName, installedVersion) } sort.SliceStable(resultSet, func(i, j int) bool { diff --git a/internal/controllers/clusterextension_controller_test.go b/internal/controllers/clusterextension_controller_test.go index 5f5b7fdb4c..4fefc5a20b 100644 --- a/internal/controllers/clusterextension_controller_test.go +++ b/internal/controllers/clusterextension_controller_test.go @@ -29,6 +29,7 @@ import ( "github.com/operator-framework/operator-controller/internal/catalogmetadata" "github.com/operator-framework/operator-controller/internal/conditionsets" "github.com/operator-framework/operator-controller/internal/controllers" + "github.com/operator-framework/operator-controller/internal/packageerrors" "github.com/operator-framework/operator-controller/pkg/features" ) @@ -61,7 +62,7 @@ func TestClusterExtensionNonExistentPackage(t *testing.T) { t.Log("By running reconcile") res, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: extKey}) require.Equal(t, ctrl.Result{}, res) - require.EqualError(t, err, fmt.Sprintf("no package %q found", pkgName)) + require.EqualError(t, err, packageerrors.GenerateError(pkgName).Error()) t.Log("By fetching updated cluster extension after reconcile") require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) @@ -75,7 +76,7 @@ func TestClusterExtensionNonExistentPackage(t *testing.T) { require.NotNil(t, cond) require.Equal(t, metav1.ConditionFalse, cond.Status) require.Equal(t, ocv1alpha1.ReasonResolutionFailed, cond.Reason) - require.Equal(t, fmt.Sprintf("no package %q found", pkgName), cond.Message) + require.Equal(t, packageerrors.GenerateError(pkgName).Error(), cond.Message) verifyInvariants(ctx, t, reconciler.Client, clusterExtension) require.NoError(t, cl.DeleteAllOf(ctx, &ocv1alpha1.ClusterExtension{})) @@ -103,7 +104,7 @@ func TestClusterExtensionNonExistentVersion(t *testing.T) { t.Log("By running reconcile") res, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: extKey}) require.Equal(t, ctrl.Result{}, res) - require.EqualError(t, err, fmt.Sprintf(`no package %q matching version "0.50.0" found`, pkgName)) + require.EqualError(t, err, packageerrors.GenerateVersionError(pkgName, "0.50.0").Error()) t.Log("By fetching updated cluster extension after reconcile") require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) @@ -117,7 +118,7 @@ func TestClusterExtensionNonExistentVersion(t *testing.T) { require.NotNil(t, cond) require.Equal(t, metav1.ConditionFalse, cond.Status) require.Equal(t, ocv1alpha1.ReasonResolutionFailed, cond.Reason) - require.Equal(t, fmt.Sprintf(`no package %q matching version "0.50.0" found`, pkgName), cond.Message) + require.Equal(t, packageerrors.GenerateVersionError(pkgName, "0.50.0").Error(), cond.Message) cond = apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeInstalled) require.NotNil(t, cond) require.Equal(t, metav1.ConditionUnknown, cond.Status) @@ -799,7 +800,7 @@ func TestClusterExtensionVersionNoChannel(t *testing.T) { t.Log("By running reconcile") res, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: extKey}) require.Equal(t, ctrl.Result{}, res) - require.EqualError(t, err, fmt.Sprintf("no package %q matching version %q found in channel %q", pkgName, pkgVer, pkgChan)) + require.EqualError(t, err, packageerrors.GenerateVersionChannelError(pkgName, pkgVer, pkgChan).Error()) t.Log("By fetching updated cluster extension after reconcile") require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) @@ -813,7 +814,7 @@ func TestClusterExtensionVersionNoChannel(t *testing.T) { require.NotNil(t, cond) require.Equal(t, metav1.ConditionFalse, cond.Status) require.Equal(t, ocv1alpha1.ReasonResolutionFailed, cond.Reason) - require.Equal(t, fmt.Sprintf("no package %q matching version %q found in channel %q", pkgName, pkgVer, pkgChan), cond.Message) + require.Equal(t, packageerrors.GenerateVersionChannelError(pkgName, pkgVer, pkgChan).Error(), cond.Message) cond = apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeInstalled) require.NotNil(t, cond) @@ -848,7 +849,7 @@ func TestClusterExtensionNoChannel(t *testing.T) { t.Log("By running reconcile") res, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: extKey}) require.Equal(t, ctrl.Result{}, res) - require.EqualError(t, err, fmt.Sprintf("no package %q found in channel %q", pkgName, pkgChan)) + require.EqualError(t, err, packageerrors.GenerateChannelError(pkgName, pkgChan).Error()) t.Log("By fetching updated cluster extension after reconcile") require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) @@ -862,7 +863,7 @@ func TestClusterExtensionNoChannel(t *testing.T) { require.NotNil(t, cond) require.Equal(t, metav1.ConditionFalse, cond.Status) require.Equal(t, ocv1alpha1.ReasonResolutionFailed, cond.Reason) - require.Equal(t, fmt.Sprintf("no package %q found in channel %q", pkgName, pkgChan), cond.Message) + require.Equal(t, packageerrors.GenerateChannelError(pkgName, pkgChan).Error(), cond.Message) cond = apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeInstalled) require.NotNil(t, cond) require.Equal(t, metav1.ConditionUnknown, cond.Status) @@ -898,7 +899,7 @@ func TestClusterExtensionNoVersion(t *testing.T) { t.Log("By running reconcile") res, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: extKey}) require.Equal(t, ctrl.Result{}, res) - require.EqualError(t, err, fmt.Sprintf("no package %q matching version %q found in channel %q", pkgName, pkgVer, pkgChan)) + require.EqualError(t, err, packageerrors.GenerateVersionChannelError(pkgName, pkgVer, pkgChan).Error()) t.Log("By fetching updated cluster extension after reconcile") require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) @@ -912,7 +913,7 @@ func TestClusterExtensionNoVersion(t *testing.T) { require.NotNil(t, cond) require.Equal(t, metav1.ConditionFalse, cond.Status) require.Equal(t, ocv1alpha1.ReasonResolutionFailed, cond.Reason) - require.Equal(t, fmt.Sprintf("no package %q matching version %q found in channel %q", pkgName, pkgVer, pkgChan), cond.Message) + require.Equal(t, packageerrors.GenerateVersionChannelError(pkgName, pkgVer, pkgChan).Error(), cond.Message) cond = apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeInstalled) require.NotNil(t, cond) require.Equal(t, metav1.ConditionUnknown, cond.Status) diff --git a/internal/packageerrors/packageerrors.go b/internal/packageerrors/packageerrors.go new file mode 100644 index 0000000000..a36ae8b36e --- /dev/null +++ b/internal/packageerrors/packageerrors.go @@ -0,0 +1,35 @@ +package packageerrors + +import ( + "fmt" +) + +func GenerateError(packageName string) error { + return GenerateFullError(packageName, "", "", "") +} + +func GenerateVersionError(packageName, versionRange string) error { + return GenerateFullError(packageName, versionRange, "", "") +} + +func GenerateChannelError(packageName, channelName string) error { + return GenerateFullError(packageName, "", channelName, "") +} + +func GenerateVersionChannelError(packageName, versionRange, channelName string) error { + return GenerateFullError(packageName, versionRange, channelName, "") +} + +func GenerateFullError(packageName, versionRange, channelName, installedVersion string) error { + var versionError, channelError, existingVersionError string + if versionRange != "" { + versionError = fmt.Sprintf(" matching version %q", versionRange) + } + if channelName != "" { + channelError = fmt.Sprintf(" in channel %q", channelName) + } + if installedVersion != "" { + existingVersionError = fmt.Sprintf(" which upgrades currently installed version %q", installedVersion) + } + return fmt.Errorf("no package %q%s%s%s found", packageName, versionError, channelError, existingVersionError) +} diff --git a/internal/resolution/variablesources/required_package.go b/internal/resolution/variablesources/required_package.go index 2f23a60622..d0b69e0fea 100644 --- a/internal/resolution/variablesources/required_package.go +++ b/internal/resolution/variablesources/required_package.go @@ -10,6 +10,7 @@ import ( "github.com/operator-framework/operator-controller/internal/catalogmetadata" catalogfilter "github.com/operator-framework/operator-controller/internal/catalogmetadata/filter" catalogsort "github.com/operator-framework/operator-controller/internal/catalogmetadata/sort" + "github.com/operator-framework/operator-controller/internal/packageerrors" olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" ) @@ -42,16 +43,7 @@ func MakeRequiredPackageVariables(allBundles []*catalogmetadata.Bundle, clusterE resultSet := catalogfilter.Filter(allBundles, catalogfilter.And(predicates...)) if len(resultSet) == 0 { - if versionRange != "" && channelName != "" { - return nil, fmt.Errorf("no package %q matching version %q found in channel %q", packageName, versionRange, channelName) - } - if versionRange != "" { - return nil, fmt.Errorf("no package %q matching version %q found", packageName, versionRange) - } - if channelName != "" { - return nil, fmt.Errorf("no package %q found in channel %q", packageName, channelName) - } - return nil, fmt.Errorf("no package %q found", packageName) + return nil, packageerrors.GenerateVersionChannelError(packageName, versionRange, channelName) } sort.SliceStable(resultSet, func(i, j int) bool { return catalogsort.ByVersion(resultSet[i], resultSet[j]) diff --git a/internal/resolution/variablesources/required_package_test.go b/internal/resolution/variablesources/required_package_test.go index 164f9a411f..a7e7f76379 100644 --- a/internal/resolution/variablesources/required_package_test.go +++ b/internal/resolution/variablesources/required_package_test.go @@ -18,6 +18,7 @@ import ( ocv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1" "github.com/operator-framework/operator-controller/internal/catalogmetadata" + "github.com/operator-framework/operator-controller/internal/packageerrors" olmvariables "github.com/operator-framework/operator-controller/internal/resolution/variables" "github.com/operator-framework/operator-controller/internal/resolution/variablesources" ) @@ -208,28 +209,28 @@ func TestMakeRequiredPackageVariables(t *testing.T) { clusterExtensions: []ocv1alpha1.ClusterExtension{ fakeClusterExtension("non-existent-test-package", "", ""), }, - expectedError: `no package "non-existent-test-package" found`, + expectedError: packageerrors.GenerateError("non-existent-test-package").Error(), }, { name: "not found: package name and channel", clusterExtensions: []ocv1alpha1.ClusterExtension{ fakeClusterExtension("non-existent-test-package", "stable", ""), }, - expectedError: `no package "non-existent-test-package" found in channel "stable"`, + expectedError: packageerrors.GenerateChannelError("non-existent-test-package", "stable").Error(), }, { name: "not found: package name and version range", clusterExtensions: []ocv1alpha1.ClusterExtension{ fakeClusterExtension("non-existent-test-package", "", "1.0.0"), }, - expectedError: `no package "non-existent-test-package" matching version "1.0.0" found`, + expectedError: packageerrors.GenerateVersionError("non-existent-test-package", "1.0.0").Error(), }, { name: "not found: package name with channel and version range", clusterExtensions: []ocv1alpha1.ClusterExtension{ fakeClusterExtension("non-existent-test-package", "stable", "1.0.0"), }, - expectedError: `no package "non-existent-test-package" matching version "1.0.0" found in channel "stable"`, + expectedError: packageerrors.GenerateVersionChannelError("non-existent-test-package", "1.0.0", "stable").Error(), }, } { t.Run(tt.name, func(t *testing.T) {