Skip to content

Commit 82e8ebb

Browse files
authored
Add ability to configure storage to scorecard (operator-framework#5028)
* Add initial implementation of storage configuration support * add exec and gather logic * remove config labels for storage and replace with the v1alpha3 storage spec to hold the mountPath, mountPath in the spec triggers storage to be added * Bump operator-framework/api dependency * Regenerate samples Co-authored-by: jmccormick2001 <[email protected]> Signed-off-by: Fabian von Feilitzsch <[email protected]>
1 parent d0fc434 commit 82e8ebb

File tree

12 files changed

+363
-11
lines changed

12 files changed

+363
-11
lines changed

Diff for: go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2
1313
github.com/onsi/ginkgo v1.16.4
1414
github.com/onsi/gomega v1.13.0
15-
github.com/operator-framework/api v0.10.0
15+
github.com/operator-framework/api v0.10.2
1616
github.com/operator-framework/java-operator-plugins v0.0.0-20210708174638-463fb91f3d5e
1717
github.com/operator-framework/operator-lib v0.5.0
1818
github.com/operator-framework/operator-registry v1.17.4

Diff for: go.sum

+2-1
Original file line numberDiff line numberDiff line change
@@ -822,8 +822,9 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
822822
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
823823
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
824824
github.com/operator-framework/api v0.7.1/go.mod h1:L7IvLd/ckxJEJg/t4oTTlnHKAJIP/p51AvEslW3wYdY=
825-
github.com/operator-framework/api v0.10.0 h1:TaxbgbrV8D3wnKNyrImZ2zjQVVHMQRc7piWLDmlGoEE=
826825
github.com/operator-framework/api v0.10.0/go.mod h1:tV0BUNvly7szq28ZPBXhjp1Sqg5yHCOeX19ui9K4vjI=
826+
github.com/operator-framework/api v0.10.2 h1:fo8Bhyx1v46NdJIz2rUzfzNUpe1KDNPtVpHVpuxZnk0=
827+
github.com/operator-framework/api v0.10.2/go.mod h1:tV0BUNvly7szq28ZPBXhjp1Sqg5yHCOeX19ui9K4vjI=
827828
github.com/operator-framework/java-operator-plugins v0.0.0-20210708174638-463fb91f3d5e h1:LMsT59IJqaLn7kD6DnZFy0IouRufXyJHTT+mXQrl9Ps=
828829
github.com/operator-framework/java-operator-plugins v0.0.0-20210708174638-463fb91f3d5e/go.mod h1:sGKGELFkUeRqElcyvyPC89bC76YnCL7MPMa13P0AQcw=
829830
github.com/operator-framework/operator-lib v0.5.0 h1:Jmhz/WjcstEyBBM9IFUiHEgKg5bd43uF4ej/ZY2S0rM=

Diff for: internal/cmd/operator-sdk/scorecard/cmd.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type scorecardCmd struct {
4949
list bool
5050
skipCleanup bool
5151
waitTime time.Duration
52+
testOutput string
5253
}
5354

5455
func NewCmd() *cobra.Command {
@@ -85,6 +86,8 @@ If the argument holds an image tag, it must be present remotely.`,
8586
"Disable resource cleanup after tests are run")
8687
scorecardCmd.Flags().DurationVarP(&c.waitTime, "wait-time", "w", 30*time.Second,
8788
"seconds to wait for tests to complete. Example: 35s")
89+
scorecardCmd.Flags().StringVarP(&c.testOutput, "test-output", "t", "test-output",
90+
"Test output directory.")
8891

8992
return scorecardCmd
9093
}
@@ -196,11 +199,12 @@ func (c *scorecardCmd) run() (err error) {
196199
ServiceAccount: c.serviceAccount,
197200
Namespace: scorecard.GetKubeNamespace(c.kubeconfig, c.namespace),
198201
BundlePath: c.bundle,
202+
TestOutput: c.testOutput,
199203
BundleMetadata: metadata,
200204
}
201205

202206
// Only get the client if running tests.
203-
if runner.Client, err = scorecard.GetKubeClient(c.kubeconfig); err != nil {
207+
if runner.Client, runner.RESTConfig, err = scorecard.GetKubeClient(c.kubeconfig); err != nil {
204208
return fmt.Errorf("error getting kubernetes client: %w", err)
205209
}
206210

Diff for: internal/scorecard/kubeclient.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
2121
"k8s.io/client-go/kubernetes"
22+
"k8s.io/client-go/rest"
2223
"k8s.io/client-go/tools/clientcmd"
2324
cruntime "sigs.k8s.io/controller-runtime/pkg/client/config"
2425
)
@@ -30,24 +31,24 @@ import (
3031
// - in-cluster connection for when the sdk is run within a cluster instead of
3132
// the command line
3233
// TODO(joelanford): migrate scorecard use `internal/operator.Configuration`
33-
func GetKubeClient(kubeconfig string) (client kubernetes.Interface, err error) {
34+
func GetKubeClient(kubeconfig string) (client kubernetes.Interface, config *rest.Config, err error) {
3435

3536
if kubeconfig != "" {
3637
os.Setenv(k8sutil.KubeConfigEnvVar, kubeconfig)
3738
}
3839

39-
config, err := cruntime.GetConfig()
40+
config, err = cruntime.GetConfig()
4041
if err != nil {
41-
return client, err
42+
return client, config, err
4243
}
4344

4445
// create the clientset
4546
clientset, err := kubernetes.NewForConfig(config)
4647
if err != nil {
47-
return client, err
48+
return client, config, err
4849
}
4950

50-
return clientset, err
51+
return clientset, config, err
5152
}
5253

5354
// GetKubeNamespace returns the kubernetes namespace to use

Diff for: internal/scorecard/scorecard.go

+37-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"k8s.io/apimachinery/pkg/labels"
2727
"k8s.io/apimachinery/pkg/util/wait"
2828
"k8s.io/client-go/kubernetes"
29+
"k8s.io/client-go/rest"
2930

3031
registryutil "github.com/operator-framework/operator-sdk/internal/registry"
3132
)
@@ -47,8 +48,10 @@ type PodTestRunner struct {
4748
Namespace string
4849
ServiceAccount string
4950
BundlePath string
51+
TestOutput string
5052
BundleMetadata registryutil.Labels
5153
Client kubernetes.Interface
54+
RESTConfig *rest.Config
5255

5356
configMapName string
5457
}
@@ -75,6 +78,7 @@ func (o Scorecard) Run(ctx context.Context) (testOutput v1alpha3.TestList, err e
7578
if len(tests) == 0 {
7679
continue
7780
}
81+
tests = o.setTestDefaults(tests)
7882

7983
output := make(chan v1alpha3.Test, len(tests))
8084
if stage.Parallel {
@@ -107,6 +111,15 @@ func (o Scorecard) Run(ctx context.Context) (testOutput v1alpha3.TestList, err e
107111
return testOutput, err
108112
}
109113

114+
func (o Scorecard) setTestDefaults(tests []v1alpha3.TestConfiguration) []v1alpha3.TestConfiguration {
115+
for i := range tests {
116+
if len(tests[i].Storage.Spec.MountPath.Path) == 0 {
117+
tests[i].Storage.Spec.MountPath.Path = o.Config.Storage.Spec.MountPath.Path
118+
}
119+
}
120+
return tests
121+
}
122+
110123
func (o Scorecard) runStageParallel(ctx context.Context, tests []v1alpha3.TestConfiguration, results chan<- v1alpha3.Test) {
111124
var wg sync.WaitGroup
112125
for _, t := range tests {
@@ -172,6 +185,7 @@ func (r *PodTestRunner) Initialize(ctx context.Context) error {
172185
if err != nil {
173186
return fmt.Errorf("error creating ConfigMap %w", err)
174187
}
188+
175189
return nil
176190

177191
}
@@ -187,6 +201,7 @@ func (r FakeTestRunner) Cleanup(ctx context.Context) error {
187201

188202
// Cleanup deletes pods and configmap resources from this test run
189203
func (r PodTestRunner) Cleanup(ctx context.Context) (err error) {
204+
190205
err = r.deletePods(ctx, r.configMapName)
191206
if err != nil {
192207
return err
@@ -195,13 +210,20 @@ func (r PodTestRunner) Cleanup(ctx context.Context) (err error) {
195210
if err != nil {
196211
return err
197212
}
213+
198214
return nil
199215
}
200216

201217
// RunTest executes a single test
202218
func (r PodTestRunner) RunTest(ctx context.Context, test v1alpha3.TestConfiguration) (*v1alpha3.TestStatus, error) {
219+
203220
// Create a Pod to run the test
204221
podDef := getPodDefinition(r.configMapName, test, r)
222+
223+
if test.Storage.Spec.MountPath.Path != "" {
224+
addStorageToPod(podDef, test.Storage.Spec.MountPath.Path)
225+
}
226+
205227
pod, err := r.Client.CoreV1().Pods(r.Namespace).Create(ctx, podDef, metav1.CreateOptions{})
206228
if err != nil {
207229
return nil, err
@@ -212,6 +234,14 @@ func (r PodTestRunner) RunTest(ctx context.Context, test v1alpha3.TestConfigurat
212234
return nil, err
213235
}
214236

237+
// gather test output if necessary
238+
if test.Storage.Spec.MountPath.Path != "" {
239+
err := gatherTestOutput(r, test.Labels["suite"], test.Labels["test"], pod.Name, test.Storage.Spec.MountPath.Path)
240+
if err != nil {
241+
return nil, err
242+
}
243+
}
244+
215245
return r.getTestStatus(ctx, pod), nil
216246
}
217247

@@ -239,9 +269,14 @@ func (r PodTestRunner) waitForTestToComplete(ctx context.Context, p *v1.Pod) (er
239269
if err != nil {
240270
return true, fmt.Errorf("error getting pod %s %w", p.Name, err)
241271
}
242-
if tmp.Status.Phase == v1.PodSucceeded || tmp.Status.Phase == v1.PodFailed {
243-
return true, nil
272+
for _, s := range tmp.Status.ContainerStatuses {
273+
if s.Name == "scorecard-test" {
274+
if s.State.Terminated != nil {
275+
return true, nil
276+
}
277+
}
244278
}
279+
245280
return false, nil
246281
})
247282

0 commit comments

Comments
 (0)