diff --git a/internal/operator-controller/applier/helm_test.go b/internal/operator-controller/applier/helm_test.go index faaa41783..5b0451789 100644 --- a/internal/operator-controller/applier/helm_test.go +++ b/internal/operator-controller/applier/helm_test.go @@ -101,7 +101,8 @@ func (mag *mockActionGetter) Reconcile(rel *release.Release) error { var ( // required for unmockable call to convert.RegistryV1ToHelmChart validFS = fstest.MapFS{ - "metadata/annotations.yaml": &fstest.MapFile{Data: []byte("{}")}, + "metadata/annotations.yaml": &fstest.MapFile{Data: []byte(`annotations: + operators.operatorframework.io.bundle.package.v1: my-package`)}, "manifests": &fstest.MapFile{Data: []byte(`apiVersion: operators.operatorframework.io/v1alpha1 kind: ClusterServiceVersion metadata: diff --git a/internal/operator-controller/rukpak/convert/validator.go b/internal/operator-controller/rukpak/convert/validator.go index 73060faa2..e0e8135eb 100644 --- a/internal/operator-controller/rukpak/convert/validator.go +++ b/internal/operator-controller/rukpak/convert/validator.go @@ -25,6 +25,7 @@ var RegistryV1BundleValidator = BundleValidator{ CheckDeploymentSpecUniqueness, CheckCRDResourceUniqueness, CheckOwnedCRDExistence, + CheckPackageNameNotEmpty, } // CheckDeploymentSpecUniqueness checks that each strategy deployment spec in the csv has a unique name. @@ -39,8 +40,7 @@ func CheckDeploymentSpecUniqueness(rv1 *RegistryV1) []error { deploymentNameSet.Insert(dep.Name) } - //nolint:prealloc - var errs []error + errs := make([]error, 0, len(duplicateDeploymentNames)) for _, d := range slices.Sorted(slices.Values(duplicateDeploymentNames.UnsortedList())) { errs = append(errs, fmt.Errorf("cluster service version contains duplicate strategy deployment spec '%s'", d)) } @@ -54,8 +54,6 @@ func CheckOwnedCRDExistence(rv1 *RegistryV1) []error { crdsNames.Insert(crd.Name) } - //nolint:prealloc - var errs []error missingCRDNames := sets.Set[string]{} for _, crd := range rv1.CSV.Spec.CustomResourceDefinitions.Owned { if !crdsNames.Has(crd.Name) { @@ -63,6 +61,7 @@ func CheckOwnedCRDExistence(rv1 *RegistryV1) []error { } } + errs := make([]error, 0, len(missingCRDNames)) for _, crdName := range slices.Sorted(slices.Values(missingCRDNames.UnsortedList())) { errs = append(errs, fmt.Errorf("cluster service definition references owned custom resource definition '%s' not found in bundle", crdName)) } @@ -80,10 +79,17 @@ func CheckCRDResourceUniqueness(rv1 *RegistryV1) []error { crdsNames.Insert(crd.Name) } - //nolint:prealloc - var errs []error + errs := make([]error, 0, len(duplicateCRDNames)) for _, crdName := range slices.Sorted(slices.Values(duplicateCRDNames.UnsortedList())) { errs = append(errs, fmt.Errorf("bundle contains duplicate custom resource definition '%s'", crdName)) } return errs } + +// CheckPackageNameNotEmpty checks that PackageName is not empty +func CheckPackageNameNotEmpty(rv1 *RegistryV1) []error { + if rv1.PackageName == "" { + return []error{errors.New("package name is empty")} + } + return nil +} diff --git a/internal/operator-controller/rukpak/convert/validator_test.go b/internal/operator-controller/rukpak/convert/validator_test.go index 7b218fba3..99c78f40f 100644 --- a/internal/operator-controller/rukpak/convert/validator_test.go +++ b/internal/operator-controller/rukpak/convert/validator_test.go @@ -19,6 +19,7 @@ func Test_BundleValidatorHasAllValidationFns(t *testing.T) { convert.CheckDeploymentSpecUniqueness, convert.CheckCRDResourceUniqueness, convert.CheckOwnedCRDExistence, + convert.CheckPackageNameNotEmpty, } actualValidationFns := convert.RegistryV1BundleValidator @@ -60,6 +61,7 @@ func Test_CheckDeploymentSpecUniqueness(t *testing.T) { ), ), }, + expectedErrs: []error{}, }, { name: "rejects bundles with duplicate deployment strategy spec names", bundle: &convert.RegistryV1{ @@ -114,6 +116,7 @@ func Test_CRDResourceUniqueness(t *testing.T) { {ObjectMeta: metav1.ObjectMeta{Name: "b.crd.something"}}, }, }, + expectedErrs: []error{}, }, { name: "rejects bundles with duplicate custom resource definition resources", bundle: &convert.RegistryV1{CRDs: []apiextensionsv1.CustomResourceDefinition{ @@ -164,6 +167,7 @@ func Test_CheckOwnedCRDExistence(t *testing.T) { ), ), }, + expectedErrs: []error{}, }, { name: "rejects bundles with missing owned custom resource definition resources", bundle: &convert.RegistryV1{ @@ -201,6 +205,32 @@ func Test_CheckOwnedCRDExistence(t *testing.T) { } } +func Test_CheckPackageNameNotEmpty(t *testing.T) { + for _, tc := range []struct { + name string + bundle *convert.RegistryV1 + expectedErrs []error + }{ + { + name: "accepts bundles with non-empty package name", + bundle: &convert.RegistryV1{ + PackageName: "not-empty", + }, + }, { + name: "rejects bundles with empty package name", + bundle: &convert.RegistryV1{}, + expectedErrs: []error{ + errors.New("package name is empty"), + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + errs := convert.CheckPackageNameNotEmpty(tc.bundle) + require.Equal(t, tc.expectedErrs, errs) + }) + } +} + type csvOption func(version *v1alpha1.ClusterServiceVersion) func withStrategyDeploymentSpecs(strategyDeploymentSpecs ...v1alpha1.StrategyDeploymentSpec) csvOption {