Skip to content

Commit a7ebc81

Browse files
authored
Add CRD description check validation (#234)
This adds a check to the good practices validator that ensures all CRDs declared in the bundle have non-empty descriptions. Both owned and required CRDs will be checked. Note that this validates the CRD definition in the CSV, not any field in the CRD itself. Signed-off-by: Ryan King <[email protected]>
1 parent f718c91 commit a7ebc81

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

pkg/validation/internal/good_practices.go

+18
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ func validateGoodPracticesFrom(bundle *manifests.Bundle) errors.ManifestResult {
5454
for _, warn := range warns {
5555
result.Add(errors.WarnFailedValidation(warn.Error(), bundle.CSV.GetName()))
5656
}
57+
for _, warn := range validateCrdDescriptions(bundle.CSV.Spec.CustomResourceDefinitions) {
58+
result.Add(errors.WarnFailedValidation(warn.Error(), bundle.CSV.GetName()))
59+
}
5760

5861
channels := append(bundle.Channels, bundle.DefaultChannel)
5962
if warn := validateHubChannels(channels); warn != nil {
@@ -126,3 +129,18 @@ func getUniqueValues(array []string) []string {
126129
}
127130
return result
128131
}
132+
133+
// validateCrdDescrptions ensures that all CRDs defined in the bundle have non-empty descriptions.
134+
func validateCrdDescriptions(crds operatorsv1alpha1.CustomResourceDefinitions) []error {
135+
f := func(crds []operatorsv1alpha1.CRDDescription, relation string) []error {
136+
errors := make([]error, 0, len(crds))
137+
for _, crd := range crds {
138+
if crd.Description == "" {
139+
errors = append(errors, fmt.Errorf("%s CRD %q has an empty description", relation, crd.Name))
140+
}
141+
}
142+
return errors
143+
}
144+
145+
return append(f(crds.Owned, "owned"), f(crds.Required, "required")...)
146+
}

pkg/validation/internal/good_practices_test.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
package internal
22

33
import (
4+
"testing"
5+
46
"github.com/operator-framework/api/pkg/manifests"
57
"github.com/stretchr/testify/require"
6-
"testing"
78
)
89

910
func Test_ValidateGoodPractices(t *testing.T) {
1011
bundleWithDeploymentSpecEmpty, _ := manifests.GetBundleFromDir("./testdata/valid_bundle")
1112
bundleWithDeploymentSpecEmpty.CSV.Spec.InstallStrategy.StrategySpec.DeploymentSpecs = nil
1213

14+
bundleWithMissingCrdDescription, _ := manifests.GetBundleFromDir("./testdata/valid_bundle")
15+
bundleWithMissingCrdDescription.CSV.Spec.CustomResourceDefinitions.Owned[0].Description = ""
16+
1317
type args struct {
1418
bundleDir string
1519
bundle *manifests.Bundle
@@ -70,6 +74,14 @@ func Test_ValidateGoodPractices(t *testing.T) {
7074
},
7175
warnStrings: []string{"Warning: Value memcached-operator.v0.0.1: channel(s) [\"alpha\"] are not following the recommended naming convention: https://olm.operatorframework.io/docs/best-practices/channel-naming"},
7276
},
77+
{
78+
name: "should raise a warn when a CRD does not have a description",
79+
wantWarning: true,
80+
args: args{
81+
bundle: bundleWithMissingCrdDescription,
82+
},
83+
warnStrings: []string{"Warning: Value etcdoperator.v0.9.4: owned CRD \"etcdclusters.etcd.database.coreos.com\" has an empty description"},
84+
},
7385
}
7486

7587
for _, tt := range tests {

0 commit comments

Comments
 (0)