Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
updates based on PR comments
  • Loading branch information
estroz committed Jul 23, 2020
commit 75b2dfc6874ac2b141f0486c3e207a4954838599
2 changes: 1 addition & 1 deletion cmd/operator-sdk/generate/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ func (c bundleCmd) generateMetadata(cfg *config.Config, manifestsDir, outputDir
return nil
}

// NB(estroz): these updates need to be atomic because the bundle's Dockerfile and annotations.yaml
// TODO(estroz): these updates need to be atomic because the bundle's Dockerfile and annotations.yaml
// cannot be out-of-sync.
func updateMetadata(cfg *config.Config, bundleRoot string) error {
bundleLabels := metricsannotations.MakeBundleMetadataLabels(cfg)
Expand Down
10 changes: 7 additions & 3 deletions internal/generate/collector/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ func (c *Manifests) UpdateFromDirs(deployDir, crdsDir string) error {
case "MutatingWebhookConfiguration":
err = c.addMutatingWebhookConfigurations(manifest)
case scorecardv1alpha3.ConfigurationKind:
err = c.addScorecardConfig(manifest)
if gvk.GroupVersion() == scorecardv1alpha3.SchemeGroupVersion {
err = c.addScorecardConfig(manifest)
}
default:
err = c.addOthers(manifest)
}
Expand Down Expand Up @@ -152,7 +154,9 @@ func (c *Manifests) UpdateFromReader(r io.Reader) error {
case "MutatingWebhookConfiguration":
err = c.addMutatingWebhookConfigurations(manifest)
case scorecardv1alpha3.ConfigurationKind:
err = c.addScorecardConfig(manifest)
if gvk.GroupVersion() == scorecardv1alpha3.SchemeGroupVersion {
err = c.addScorecardConfig(manifest)
}
default:
err = c.addOthers(manifest)
}
Expand Down Expand Up @@ -273,7 +277,7 @@ func (c *Manifests) addScorecardConfig(rawManifest []byte) error {
return err
}
if c.ScorecardConfig.Metadata.Name != "" {
return errors.New("duplicate ScorecardConfigurations in collector input")
return errors.New("duplicate scorecard configurations in collector input")
}
c.ScorecardConfig = cfg
return nil
Expand Down
11 changes: 1 addition & 10 deletions internal/plugins/golang/v2/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ package v2

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/spf13/pflag"
"sigs.k8s.io/kubebuilder/pkg/model/config"
Expand Down Expand Up @@ -54,14 +51,8 @@ func (p *initPlugin) Run() error {
return err
}

// Assume projectName was validated by go.kubebuilder.io.
wd, err := os.Getwd()
if err != nil {
return fmt.Errorf("error getting the current path: %v", err)
}
projectName := strings.ToLower(filepath.Base(wd))
// Run the scorecard "phase 2" plugin.
if err := scorecard.RunInit(projectName); err != nil {
if err := scorecard.RunInit(p.config); err != nil {
return err
}

Expand Down
8 changes: 1 addition & 7 deletions internal/plugins/helm/v1/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,8 @@ func (p *initPlugin) Run() error {
return err
}

// Assume projectName was validated by Validate().
wd, err := os.Getwd()
if err != nil {
return fmt.Errorf("error getting the current path: %v", err)
}
projectName := strings.ToLower(filepath.Base(wd))
// Run the scorecard "phase 2" plugin.
if err := scorecard.RunInit(projectName); err != nil {
if err := scorecard.RunInit(p.config); err != nil {
return err
}

Expand Down
88 changes: 48 additions & 40 deletions internal/plugins/scorecard/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@ import (
"path/filepath"
"text/template"

"github.com/operator-framework/operator-registry/pkg/registry"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/kubebuilder/pkg/model/config"
"sigs.k8s.io/yaml"

"github.com/operator-framework/operator-sdk/internal/scaffold/kustomize"
"github.com/operator-framework/operator-sdk/internal/scorecard"
"github.com/operator-framework/operator-sdk/pkg/apis/scorecard/v1alpha3"
)

// kustomization.yaml file template for the scorecard componentconfig. This should always be written to
// config/scorecard/kustomization.yaml since it only references files in config.
const scorecardKustomizationTemplate = `resources:
const (
// kustomization.yaml file template for the scorecard componentconfig. This should always be written to
// config/scorecard/kustomization.yaml since it only references files in config.
scorecardKustomizationTemplate = `resources:
{{- range $i, $path := .ResourcePaths }}
- {{ $path }}
{{- end }}
Expand All @@ -47,24 +49,28 @@ patchesJson6902:
{{- end }}
`

// YAML file fragment to append to kustomization.yaml files.
kubebuilderScaffoldMarkerFragment = "# +kubebuilder:scaffold:patchesJson6902\n"
)

const (
// defaultTestImageTag points to the latest-released image.
// TODO: change the tag to "latest" once config scaffolding is in a release,
// as the new config spec won't work with the current latest image.
defaultTestImageTag = "quay.io/operator-framework/scorecard-test:master"

// scorecardConfigName is the default scorecard componentconfig's metadata.name,
// defaultConfigName is the default scorecard componentconfig's metadata.name,
// which must be set on all kustomize-able bases. This name is only used for
// `kustomize build` pattern match and not for on-cluster creation.
scorecardConfigName = "config"
defaultConfigName = "config"
)

// defaultDir is the default directory in which to generate kustomize bases and the kustomization.yaml.
var defaultDir = filepath.Join("config", "scorecard")

// RunInit scaffolds kustomize files for kustomizing a scorecard componentconfig.
func RunInit(projectName string) error {
return generate(projectName, defaultTestImageTag, defaultDir)
func RunInit(*config.Config) error {
return generate(defaultTestImageTag, defaultDir)
}

// scorecardKustomizationValues holds data required to generate a scorecard's kustomization.yaml.
Expand All @@ -76,12 +82,18 @@ type scorecardKustomizationValues struct {
// kustomizationJSON6902Patch holds path and target data to write a patchesJson6902 list in a kustomization.yaml.
type kustomizationJSON6902Patch struct {
Path string
Target registry.DefinitionKey
Target patchTarget
}

// patchTarget holds target data for a kustomize patch.
type patchTarget struct {
schema.GroupVersionKind
Name string
}

// generate scaffolds kustomize bundle bases and a kustomization.yaml.
// TODO(estroz): refactor this to be testable (in-mem fs) and easier to read.
func generate(operatorName, testImageTag, outputDir string) error {
func generate(testImageTag, outputDir string) error {

kustomizationValues := scorecardKustomizationValues{}

Expand All @@ -91,7 +103,7 @@ func generate(operatorName, testImageTag, outputDir string) error {
return err
}

configBase := newScorecardConfigurationBase()
configBase := newConfigurationBase(defaultConfigName)
b, err := yaml.Marshal(configBase)
if err != nil {
return fmt.Errorf("error marshaling default config: %v", err)
Expand All @@ -102,11 +114,9 @@ func generate(operatorName, testImageTag, outputDir string) error {
return fmt.Errorf("error writing default scorecard config: %v", err)
}
kustomizationValues.ResourcePaths = append(kustomizationValues.ResourcePaths, relBasePath)
scorecardConfigTarget := registry.DefinitionKey{
Group: v1alpha3.SchemeGroupVersion.Group,
Version: v1alpha3.SchemeGroupVersion.Version,
Kind: v1alpha3.ConfigurationKind,
Name: scorecardConfigName,
scorecardConfigTarget := patchTarget{
GroupVersionKind: v1alpha3.SchemeGroupVersion.WithKind(v1alpha3.ConfigurationKind),
Name: defaultConfigName,
}

// Config patches.
Expand All @@ -116,7 +126,7 @@ func generate(operatorName, testImageTag, outputDir string) error {
}

// Basic scorecard tests patch.
basicPatch := newBasicScorecardConfigurationPatch(operatorName, testImageTag)
basicPatch := newBasicConfigurationPatch(testImageTag)
b, err = yaml.Marshal(basicPatch)
if err != nil {
return fmt.Errorf("error marshaling basic patch config: %v", err)
Expand All @@ -131,7 +141,7 @@ func generate(operatorName, testImageTag, outputDir string) error {
})

// OLM scorecard tests patch.
olmPatch := newOLMScorecardConfigurationPatch(operatorName, testImageTag)
olmPatch := newOLMConfigurationPatch(testImageTag)
b, err = yaml.Marshal(olmPatch)
if err != nil {
return fmt.Errorf("error marshaling OLM patch config: %v", err)
Expand All @@ -154,6 +164,8 @@ func generate(operatorName, testImageTag, outputDir string) error {
if err = t.Execute(&buf, kustomizationValues); err != nil {
return fmt.Errorf("error executing on default kustomize template: %v", err)
}
// Append the kubebuilder scaffold marker to make updates to this file in the future.
buf.Write([]byte(kubebuilderScaffoldMarkerFragment))
if err := kustomize.Write(outputDir, buf.String()); err != nil {
return fmt.Errorf("error writing default scorecard kustomization.yaml: %v", err)
}
Expand All @@ -172,11 +184,11 @@ type jsonPatchObject struct {
Value v1alpha3.TestConfiguration `json:"value"`
}

// newScorecardConfigurationBase returns a scorecard componentconfig object with one parallel stage.
// newConfigurationBase returns a scorecard componentconfig object with one parallel stage.
// The returned object is intended to be marshaled and written to disk as a kustomize base.
func newScorecardConfigurationBase() (cfg v1alpha3.Configuration) {
func newConfigurationBase(configName string) (cfg v1alpha3.Configuration) {
cfg.SetGroupVersionKind(v1alpha3.SchemeGroupVersion.WithKind(v1alpha3.ConfigurationKind))
cfg.Metadata.Name = scorecardConfigName
cfg.Metadata.Name = configName
cfg.Stages = []v1alpha3.StageConfiguration{
{
Parallel: true,
Expand All @@ -186,57 +198,54 @@ func newScorecardConfigurationBase() (cfg v1alpha3.Configuration) {
return cfg
}

func makeTestStageJSONPath(stageIdx, testIdx int) string {
return fmt.Sprintf("/stages/%d/tests/%d", stageIdx, testIdx)
}
const defaultJSONPath = "/stages/0/tests/-"

// newBasicScorecardConfigurationPatch returns default "basic" test configurations as JSON patch objects
// newBasicConfigurationPatch returns default "basic" test configurations as JSON patch objects
// to be inserted into the componentconfig base as a first stage test element.
// The returned patches are intended to be marshaled and written to disk as in a kustomize patch file.
func newBasicScorecardConfigurationPatch(operatorName, testImageTag string) (ps jsonPatches) {
for i, cfg := range makeDefaultBasicTestConfigs(operatorName, testImageTag) {
func newBasicConfigurationPatch(testImageTag string) (ps jsonPatches) {
for _, cfg := range makeDefaultBasicTestConfigs(testImageTag) {
ps = append(ps, jsonPatchObject{
Op: "add",
Path: makeTestStageJSONPath(0, i),
Path: defaultJSONPath,
Value: cfg,
})
}
return ps
}

// makeDefaultBasicTestConfigs returns all default "basic" test configurations.
func makeDefaultBasicTestConfigs(operatorName, testImageTag string) (cfgs []v1alpha3.TestConfiguration) {
func makeDefaultBasicTestConfigs(testImageTag string) (cfgs []v1alpha3.TestConfiguration) {
for _, testName := range []string{"basic-check-spec"} {
cfgs = append(cfgs, v1alpha3.TestConfiguration{
Image: testImageTag,
Entrypoint: []string{"scorecard-test", testName},
Labels: map[string]string{
"operator": operatorName,
"suite": "basic",
"test": fmt.Sprintf("%s-test", testName),
"suite": "basic",
"test": fmt.Sprintf("%s-test", testName),
},
})
}

return cfgs
}

// newOLMScorecardConfigurationPatch returns default "olm" test configurations as JSON patch objects
// newOLMConfigurationPatch returns default "olm" test configurations as JSON patch objects
// to be inserted into the componentconfig base as a first stage test element.
// The returned patches are intended to be marshaled and written to disk as in a kustomize patch file.
func newOLMScorecardConfigurationPatch(operatorName, testImageTag string) (ps jsonPatches) {
for i, cfg := range makeDefaultOLMTestConfigs(operatorName, testImageTag) {
func newOLMConfigurationPatch(testImageTag string) (ps jsonPatches) {
for _, cfg := range makeDefaultOLMTestConfigs(testImageTag) {
ps = append(ps, jsonPatchObject{
Op: "add",
Path: makeTestStageJSONPath(0, i),
Path: defaultJSONPath,
Value: cfg,
})
}
return ps
}

// makeDefaultOLMTestConfigs returns all default "olm" test configurations.
func makeDefaultOLMTestConfigs(operatorName, testImageTag string) (cfgs []v1alpha3.TestConfiguration) {
func makeDefaultOLMTestConfigs(testImageTag string) (cfgs []v1alpha3.TestConfiguration) {
for _, testName := range []string{
"olm-bundle-validation",
"olm-crds-have-validation",
Expand All @@ -248,9 +257,8 @@ func makeDefaultOLMTestConfigs(operatorName, testImageTag string) (cfgs []v1alph
Image: testImageTag,
Entrypoint: []string{"scorecard-test", testName},
Labels: map[string]string{
"operator": operatorName,
"suite": "olm",
"test": fmt.Sprintf("%s-test", testName),
"suite": "olm",
"test": fmt.Sprintf("%s-test", testName),
},
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kind: ScorecardConfiguration
kind: Configuration
apiversion: scorecard.operatorframework.io/v1alpha3
metadata:
name: config
Expand Down
4 changes: 1 addition & 3 deletions internal/scorecard/formatting.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ func (o Scorecard) List() v1alpha3.TestList {
tests := o.selectTests(stage)
for _, test := range tests {
item := v1alpha3.NewTest()
item.Spec.Image = test.Image
item.Spec.Entrypoint = test.Entrypoint
item.Spec.Labels = test.Labels
item.Spec = test
output.Items = append(output.Items, item)
}
}
Expand Down
4 changes: 1 addition & 3 deletions internal/scorecard/scorecard.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,7 @@ func (o Scorecard) runTest(ctx context.Context, test v1alpha3.TestConfiguration)
}

out := v1alpha3.NewTest()
out.Spec.Image = test.Image
out.Spec.Entrypoint = test.Entrypoint
out.Spec.Labels = test.Labels
out.Spec = test
out.Status = *result
return out
}
Expand Down
Binary file modified internal/scorecard/testdata/bundle.tar.gz
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kind: ScorecardConfiguration
kind: Configuration
apiversion: scorecard.operatorframework.io/v1alpha3
metadata:
name: config
Expand Down
3 changes: 2 additions & 1 deletion pkg/apis/scorecard/v1alpha3/configuration_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import (
)

// ConfigurationKind is the default scorecard componentconfig kind.
const ConfigurationKind = "ScorecardConfiguration"
const ConfigurationKind = "Configuration"

// Configuration represents the set of test configurations which scorecard would run.
type Configuration struct {
metav1.TypeMeta `json:",inline" yaml:",inline"`

// Do not use metav1.ObjectMeta because this "object" should not be treated as an actual object.
Metadata struct {
// Name is a required field for kustomize-able manifests, and is not used on-cluster (nor is the config itself).
Name string `json:"name,omitempty" yaml:"name,omitempty"`
} `json:"metadata,omitempty" yaml:"metadata,omitempty"`

Expand Down
14 changes: 2 additions & 12 deletions pkg/apis/scorecard/v1alpha3/test_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@ const (
ErrorState State = "error"
)

// TestSpec contains the spec details of an individual scorecard test
type TestSpec struct {
// Image is the name of the testimage
Image string `json:"image"`
// Entrypoint is list of commands and arguments passed to the test image
Entrypoint []string `json:"entrypoint,omitempty"`
// Labels that further describe the test and enable selection
Labels map[string]string `json:"labels,omitempty"`
}

// TestResult contains the results of an individual scorecard test
type TestResult struct {
// Name is the name of the test
Expand All @@ -64,8 +54,8 @@ type TestStatus struct {
// Test specifies a single test run.
type Test struct {
metav1.TypeMeta `json:",inline"`
Spec TestSpec `json:"spec,omitempty"`
Status TestStatus `json:"status,omitempty"`
Spec TestConfiguration `json:"spec,omitempty"`
Status TestStatus `json:"status,omitempty"`
}

// TestList is a list of tests.
Expand Down
Loading