Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch the bundle validate to use the API #770

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions certification/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ func initializeChecks(ctx context.Context, p policy.Policy, cfg certification.Co
return []certification.Check{
operatorpol.NewScorecardBasicSpecCheck(operatorsdk.New(cfg.ScorecardImage(), exec.Command), cfg.Namespace(), cfg.ServiceAccount(), cfg.Kubeconfig(), cfg.ScorecardWaitTime()),
operatorpol.NewScorecardOlmSuiteCheck(operatorsdk.New(cfg.ScorecardImage(), exec.Command), cfg.Namespace(), cfg.ServiceAccount(), cfg.Kubeconfig(), cfg.ScorecardWaitTime()),
operatorpol.NewDeployableByOlmCheck(operatorsdk.New(cfg.ScorecardImage(), exec.Command), cfg.IndexImage(), cfg.DockerConfig(), cfg.Channel()),
operatorpol.NewValidateOperatorBundleCheck(operatorsdk.New(cfg.ScorecardImage(), exec.Command)),
operatorpol.NewDeployableByOlmCheck(cfg.IndexImage(), cfg.DockerConfig(), cfg.Channel()),
operatorpol.NewValidateOperatorBundleCheck(),
operatorpol.NewCertifiedImagesCheck(pyxis.NewPyxisClient(
certification.DefaultPyxisHost,
"",
Expand Down
46 changes: 29 additions & 17 deletions certification/internal/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (
"path/filepath"
"strings"

"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"

"github.com/blang/semver"
"github.com/operator-framework/api/pkg/manifests"
"github.com/operator-framework/api/pkg/validation"
olmvalidation "github.com/redhat-openshift-ecosystem/ocp-olm-catalog-validator/pkg/validation"
log "github.com/sirupsen/logrus"
rbacv1 "k8s.io/api/rbac/v1"
"sigs.k8s.io/yaml"
Expand All @@ -29,21 +29,22 @@ var ocpToKubeVersion = map[string]string{

const latestReleasedVersion = "4.11"

type operatorSdk interface {
BundleValidate(context.Context, string, operatorsdk.OperatorSdkBundleValidateOptions) (*operatorsdk.OperatorSdkBundleValidateReport, error)
}
func Validate(ctx context.Context, imagePath string) (*Report, error) {
log.Trace("reading annotations file from the bundle")
log.Debug("image extraction directory is ", imagePath)

func Validate(ctx context.Context, operatorSdk operatorSdk, imagePath string) (*operatorsdk.OperatorSdkBundleValidateReport, error) {
selector := []string{"community", "operatorhub", "alpha-deprecated-apis"}
opts := operatorsdk.OperatorSdkBundleValidateOptions{
Selector: selector,
Verbose: true,
ContainerEngine: "none",
OutputFormat: "json-alpha1",
bundle, err := manifests.GetBundleFromDir(imagePath)
if err != nil {
return nil, fmt.Errorf("could not load bundle from path: %s: %v", imagePath, err)
}
validators := validation.DefaultBundleValidators.WithValidators(
validation.AlphaDeprecatedAPIsValidator,
validation.OperatorHubValidator,
olmvalidation.OpenShiftValidator,
)

objs := bundle.ObjectsToValidate()

log.Trace("reading annotations file from the bundle")
log.Debug("image extraction directory is ", imagePath)
// retrieve the operator metadata from bundle image
annotationsFileName := filepath.Join(imagePath, "metadata", "annotations.yaml")
annotationsFile, err := os.Open(annotationsFileName)
Expand All @@ -55,6 +56,7 @@ func Validate(ctx context.Context, operatorSdk operatorSdk, imagePath string) (*
return nil, fmt.Errorf("unable to get annotations.yaml from the bundle: %v", err)
}

optionalValues := make(map[string]string)
if annotations.OpenshiftVersions != "" {
// Check that the label range contains >= 4.9
targetVersion, err := targetVersion(annotations.OpenshiftVersions)
Expand All @@ -64,12 +66,22 @@ func Validate(ctx context.Context, operatorSdk operatorSdk, imagePath string) (*
}
if k8sVer, found := ocpToKubeVersion[targetVersion]; found {
log.Debugf("OpenShift %s detected in annotations. Running with additional checks enabled.", targetVersion)
opts.OptionalValues = make(map[string]string)
opts.OptionalValues["k8s-version"] = k8sVer
optionalValues = make(map[string]string)
optionalValues["k8s-version"] = k8sVer
}
}
objs = append(objs, optionalValues)

results := validators.Validate(objs...)
passed := true
for _, v := range results {
if v.HasError() {
passed = false
break
}
}

return operatorSdk.BundleValidate(ctx, imagePath, opts)
return &Report{Results: results, Passed: passed}, nil
}

func targetVersion(ocpLabelIndex string) (string, error) {
Expand Down
12 changes: 0 additions & 12 deletions certification/internal/bundle/bundle_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package bundle

import (
"context"
"errors"
"testing"

"github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/operatorsdk"

. "github.com/onsi/ginkgo/v2/dsl/core"
. "github.com/onsi/gomega"
)
Expand All @@ -16,15 +13,6 @@ func TestBundle(t *testing.T) {
RunSpecs(t, "Bundle Utils Suite")
}

type FakeOperatorSdk struct {
OperatorSdkReport operatorsdk.OperatorSdkScorecardReport
OperatorSdkBVReport operatorsdk.OperatorSdkBundleValidateReport
}

func (f FakeOperatorSdk) BundleValidate(ctx context.Context, image string, opts operatorsdk.OperatorSdkBundleValidateOptions) (*operatorsdk.OperatorSdkBundleValidateReport, error) {
return &f.OperatorSdkBVReport, nil
}

// In order to test some negative paths, this io.Reader will just throw an error
type errReader int

Expand Down
84 changes: 18 additions & 66 deletions certification/internal/bundle/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,55 @@ package bundle
import (
"bytes"
"context"
"os"
"path/filepath"

"github.com/redhat-openshift-ecosystem/openshift-preflight/certification"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/ginkgo/v2/dsl/core"
. "github.com/onsi/ginkgo/v2/dsl/table"
. "github.com/onsi/gomega"
)

var _ = Describe("BundleValidateCheck", func() {
const (
manifestsDir = "manifests"
metadataDir = "metadata"
annotationFilename = "annotations.yaml"
annotations = `annotations:
com.redhat.openshift.versions: "v4.6-v4.9"
operators.operatorframework.io.bundle.package.v1: testPackage
operators.operatorframework.io.bundle.channel.default.v1: testChannel
`
)

Describe("Bundle validation", func() {
var (
imageRef certification.ImageReference
fakeEngine operatorSdk
)

BeforeEach(func() {
// mock bundle directory
tmpDir, err := os.MkdirTemp("", "bundle-metadata-*")
Expect(err).ToNot(HaveOccurred())

err = os.Mkdir(filepath.Join(tmpDir, metadataDir), 0o755)
Expect(err).ToNot(HaveOccurred())

err = os.Mkdir(filepath.Join(tmpDir, manifestsDir), 0o755)
Expect(err).ToNot(HaveOccurred())

err = os.WriteFile(filepath.Join(tmpDir, metadataDir, annotationFilename), []byte(annotations), 0o644)
Expect(err).ToNot(HaveOccurred())

imageRef.ImageFSPath = tmpDir
fakeEngine = FakeOperatorSdk{}
})

AfterEach(func() {
err := os.RemoveAll(imageRef.ImageFSPath)
Expect(err).ToNot(HaveOccurred())
})

Context("the annotations file is valid", func() {
It("should pass", func() {
report, err := Validate(context.Background(), fakeEngine, imageRef.ImageFSPath)
imageRef := certification.ImageReference{
ImageFSPath: "./testdata/valid_bundle",
}
report, err := Validate(context.Background(), imageRef.ImageFSPath)
Expect(err).ToNot(HaveOccurred())
Expect(report).ToNot(BeNil())
})
})

Context("the annotations file does not exist", func() {
JustBeforeEach(func() {
err := os.Remove(filepath.Join(imageRef.ImageFSPath, metadataDir, annotationFilename))
Expect(err).ToNot(HaveOccurred())
})
It("should error", func() {
report, err := Validate(context.Background(), fakeEngine, imageRef.ImageFSPath)
imageRef := certification.ImageReference{
ImageFSPath: "./testdata/no_annotations_file",
}
report, err := Validate(context.Background(), imageRef.ImageFSPath)
Expect(err).To(HaveOccurred())
Expect(report).To(BeNil())
})
})

Context("the annotations file is malformed", func() {
JustBeforeEach(func() {
err := os.WriteFile(filepath.Join(imageRef.ImageFSPath, metadataDir, annotationFilename), []byte("badAnnotations"), 0o644)
Expect(err).ToNot(HaveOccurred())
})
It("should error", func() {
report, err := Validate(context.Background(), fakeEngine, imageRef.ImageFSPath)
imageRef := certification.ImageReference{
ImageFSPath: "./testdata/malformed_annotations_file",
}
report, err := Validate(context.Background(), imageRef.ImageFSPath)
Expect(err).To(HaveOccurred())
Expect(report).To(BeNil())
})
})

Context("the annotations file is valid but has no annotations", func() {
JustBeforeEach(func() {
err := os.WriteFile(filepath.Join(imageRef.ImageFSPath, metadataDir, annotationFilename), []byte("annotations:"), 0o644)
Expect(err).ToNot(HaveOccurred())
})
It("should fail gracefully", func() {
report, err := Validate(context.Background(), fakeEngine, imageRef.ImageFSPath)
imageRef := certification.ImageReference{
ImageFSPath: "./testdata/invalid_bundle",
}
report, err := Validate(context.Background(), imageRef.ImageFSPath)
Expect(err).ToNot(HaveOccurred())
Expect(report).ToNot(BeNil())
})
Expand All @@ -101,14 +61,6 @@ var _ = Describe("BundleValidateCheck", func() {
Describe("While ensuring that container util is working", func() {
// tests: extractAnnotationsBytes
Context("with an annotations yaml data read from disk", func() {
Context("with the correct format", func() {
It("should properly marshal to a map[string]string", func() {
annotations, err := LoadAnnotations(context.TODO(), bytes.NewReader([]byte(annotations)))
Expect(err).ToNot(HaveOccurred())
Expect(annotations.DefaultChannelName).To(Equal("testChannel"))
})
})

Context("containing no data read in from the yaml file", func() {
data := []byte{}

Expand Down
Empty file.
Loading