Skip to content

Commit 9d6e509

Browse files
committed
This commit modifies the scorecard config to be a componentconfig
versioned with other scorecard APIs in `pkg/apis/scorecard/v1alpha3`. It also adds the `generate kustomize scorecard` subcommand, which scaffolds componentconfig bases and patches in `config/scorecard`. `generate kustomize manifests` will add the scorecard kustomize path to the manifests kustomization.yaml, and `generate bundle` will write the scorecard config to `bundle/tests/scorecard/config.yaml` cmd/operator-sdk/generate: add `kustomize scorecard` subcommand and modify `kustomize manifests` subcommand pkg/apis/scorecard/v1alpha3: add ScorecardConfiguration types that map to the original Config's types internal/scorecard: replace Config type with v1alpha3.ScorecardConfiguration and related types
1 parent c51b80c commit 9d6e509

File tree

20 files changed

+758
-190
lines changed

20 files changed

+758
-190
lines changed

cmd/operator-sdk/generate/bundle/bundle.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/operator-framework/operator-sdk/internal/registry"
3636
"github.com/operator-framework/operator-sdk/internal/scorecard"
3737
"github.com/operator-framework/operator-sdk/internal/util/projutil"
38+
"github.com/operator-framework/operator-sdk/pkg/apis/scorecard/v1alpha3"
3839
)
3940

4041
const (
@@ -218,13 +219,37 @@ func (c bundleCmd) runManifests(cfg *config.Config) (err error) {
218219
}
219220
}
220221

222+
// Write the scorecard config if it was passed.
223+
if err := writeScorecardConfig(c.outputDir, col.ScorecardConfig); err != nil {
224+
return fmt.Errorf("error writing bundle scorecard config: %v", err)
225+
}
226+
221227
if !c.quiet && !c.stdout {
222228
fmt.Println("Bundle manifests generated successfully in", c.outputDir)
223229
}
224230

225231
return nil
226232
}
227233

234+
// writeScorecardConfig writes cfg to dir at the hard-coded config path 'config.yaml'.
235+
func writeScorecardConfig(dir string, cfg v1alpha3.ScorecardConfiguration) error {
236+
if cfg.Metadata.Name == "" {
237+
return nil
238+
}
239+
240+
b, err := yaml.Marshal(cfg)
241+
if err != nil {
242+
return err
243+
}
244+
245+
cfgDir := filepath.Join(dir, filepath.FromSlash(scorecard.DefaultConfigDir))
246+
if err := os.MkdirAll(cfgDir, 0755); err != nil {
247+
return err
248+
}
249+
scorecardConfigPath := filepath.Join(cfgDir, scorecard.ConfigFileName)
250+
return ioutil.WriteFile(scorecardConfigPath, b, 0666)
251+
}
252+
228253
// validateMetadata validates c for bundle metadata generation.
229254
func (c bundleCmd) validateMetadata(*config.Config) (err error) {
230255
// Ensure a default channel is present.
@@ -282,6 +307,8 @@ func (c bundleCmd) generateMetadata(cfg *config.Config, manifestsDir, outputDir
282307
return nil
283308
}
284309

310+
// NB(estroz): these updates need to be atomic because the bundle's Dockerfile and annotations.yaml
311+
// cannot be out-of-sync.
285312
func updateMetadata(cfg *config.Config, bundleRoot string) error {
286313
bundleLabels := metricsannotations.MakeBundleMetadataLabels(cfg)
287314
for key, value := range scorecardannotations.MakeBundleMetadataLabels(scorecard.DefaultConfigDir) {
@@ -292,8 +319,6 @@ func updateMetadata(cfg *config.Config, bundleRoot string) error {
292319
}
293320

294321
// Write labels to bundle Dockerfile.
295-
// NB(estroz): these "rewrites" need to be atomic because the bundle's Dockerfile and annotations.yaml
296-
// cannot be out-of-sync.
297322
if err := rewriteDockerfileLabels(bundle.DockerFile, bundleLabels); err != nil {
298323
return fmt.Errorf("error writing LABEL's in %s: %v", bundle.DockerFile, err)
299324
}
@@ -303,7 +328,8 @@ func updateMetadata(cfg *config.Config, bundleRoot string) error {
303328

304329
// Add a COPY for the scorecard config to bundle Dockerfile.
305330
// TODO: change input config path to be a flag-based value.
306-
err := writeDockerfileCOPYScorecardConfig(bundle.DockerFile, filepath.FromSlash(scorecard.DefaultConfigDir))
331+
localScorecardConfigPath := filepath.Join(bundleRoot, filepath.FromSlash(scorecard.DefaultConfigDir))
332+
err := writeDockerfileCOPYScorecardConfig(bundle.DockerFile, localScorecardConfigPath)
307333
if err != nil {
308334
return fmt.Errorf("error writing scorecard config COPY in %s: %v", bundle.DockerFile, err)
309335
}

cmd/operator-sdk/generate/kustomize/cmd.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ package kustomize
1616

1717
import (
1818
"github.com/spf13/cobra"
19+
20+
"github.com/operator-framework/operator-sdk/cmd/operator-sdk/generate/kustomize/scorecard"
1921
)
2022

2123
// NewCmd returns the 'kustomize' subcommand.
@@ -27,6 +29,7 @@ func NewCmd() *cobra.Command {
2729

2830
cmd.AddCommand(
2931
newManifestsCmd(),
32+
scorecard.NewCmd(),
3033
)
3134

3235
return cmd

cmd/operator-sdk/generate/kustomize/manifests.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package kustomize
1616

1717
import (
1818
"fmt"
19+
"os"
1920
"path/filepath"
2021

2122
log "github.com/sirupsen/logrus"
@@ -174,8 +175,18 @@ func (c manifestsCmd) run(cfg *config.Config) error {
174175
return fmt.Errorf("error generating kustomize bases: %v", err)
175176
}
176177

178+
// NB(estroz): this is a rather hacky way of adding scorecard componentconfigs to the bundle,
179+
// and won't work if the manifests kustomization.yaml already exists. This should be improved
180+
// with scaffolding markers.
181+
kustomization := manifestsKustomization
182+
183+
// Add a scorecard kustomization if one exists.
184+
info, err := os.Stat(filepath.Join(filepath.Dir(c.outputDir), "scorecard"))
185+
if err == nil && info.IsDir() {
186+
kustomization += "- ../scorecard\n"
187+
}
177188
// Write a kustomization.yaml to outputDir if one does not exist.
178-
if err := kustomize.WriteIfNotExist(c.outputDir, manifestsKustomization); err != nil {
189+
if err := kustomize.WriteIfNotExist(c.outputDir, kustomization); err != nil {
179190
return fmt.Errorf("error writing kustomization.yaml: %v", err)
180191
}
181192

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright 2020 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package scorecard
16+
17+
import (
18+
"fmt"
19+
"path/filepath"
20+
21+
log "github.com/sirupsen/logrus"
22+
"github.com/spf13/cobra"
23+
"github.com/spf13/pflag"
24+
"sigs.k8s.io/kubebuilder/pkg/model/config"
25+
26+
kbutil "github.com/operator-framework/operator-sdk/internal/util/kubebuilder"
27+
)
28+
29+
const scorecardLongHelp = `
30+
Running 'generate kustomize scorecard' will (re)generate scorecard configuration kustomize bases,
31+
default test patches, and a kustomization.yaml in 'config/scorecard'.
32+
`
33+
34+
const scorecardExamples = `
35+
$ operator-sdk generate kustomize scorecard
36+
Generating kustomize files in config/scorecard
37+
Kustomize files generated successfully
38+
$ tree ./config/scorecard
39+
./config/scorecard/
40+
├── bases
41+
│   └── config.yaml
42+
├── kustomization.yaml
43+
└── patches
44+
├── basic.config.yaml
45+
└── olm.config.yaml
46+
`
47+
48+
// defaultTestImageTag points to the latest-released image.
49+
const defaultTestImageTag = "quay.io/operator-framework/scorecard-test:latest"
50+
51+
type scorecardCmd struct {
52+
operatorName string
53+
outputDir string
54+
testImageTag string
55+
quiet bool
56+
}
57+
58+
// NewCmd returns the `scorecard` subcommand.
59+
func NewCmd() *cobra.Command {
60+
c := &scorecardCmd{}
61+
cmd := &cobra.Command{
62+
Use: "scorecard",
63+
Short: "Generates scorecard configuration files",
64+
Long: scorecardLongHelp,
65+
Example: scorecardExamples,
66+
RunE: func(cmd *cobra.Command, args []string) error {
67+
if len(args) != 0 {
68+
return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath())
69+
}
70+
71+
cfg, err := kbutil.ReadConfig()
72+
if err != nil {
73+
return fmt.Errorf("error reading configuration: %v", err)
74+
}
75+
c.setDefaults(cfg)
76+
77+
// Run command logic.
78+
if err = c.run(); err != nil {
79+
log.Fatalf("Error generating kustomize files: %v", err)
80+
}
81+
82+
return nil
83+
},
84+
}
85+
86+
c.addFlagsTo(cmd.Flags())
87+
88+
return cmd
89+
}
90+
91+
func (c *scorecardCmd) addFlagsTo(fs *pflag.FlagSet) {
92+
fs.StringVar(&c.operatorName, "operator-name", "", "Name of the operator")
93+
fs.StringVar(&c.outputDir, "output-dir", "", "Directory to write kustomize files")
94+
fs.StringVar(&c.testImageTag, "image", defaultTestImageTag,
95+
"Image to use for default tests; this image must contain the `/scorecard-test` binary")
96+
fs.BoolVarP(&c.quiet, "quiet", "q", false, "Run in quiet mode")
97+
// NB(estroz): might be nice to have an --overwrite flag to explicitly turn on overwrite behavior (the current default).
98+
}
99+
100+
// defaultDir is the default directory in which to generate kustomize bases and the kustomization.yaml.
101+
var defaultDir = filepath.Join("config", "scorecard")
102+
103+
// setDefaults sets command defaults.
104+
func (c *scorecardCmd) setDefaults(cfg *config.Config) {
105+
if c.operatorName == "" {
106+
c.operatorName = filepath.Base(cfg.Repo)
107+
}
108+
109+
if c.outputDir == "" {
110+
c.outputDir = defaultDir
111+
}
112+
}
113+
114+
// run scaffolds kustomize files for kustomizing a scorecard componentconfig.
115+
func (c scorecardCmd) run() error {
116+
117+
if !c.quiet {
118+
fmt.Println("Generating kustomize files in", c.outputDir)
119+
}
120+
121+
err := generate(c.operatorName, c.testImageTag, c.outputDir)
122+
if err != nil {
123+
return err
124+
}
125+
126+
if !c.quiet {
127+
fmt.Println("Kustomize files generated successfully")
128+
}
129+
130+
return nil
131+
}

0 commit comments

Comments
 (0)