Repository: aquasecurity/starboard
Pull request #600 (2021-05-25 08:52:46)

feat: Add PluginContext to vulnerability scan plugins
Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/600?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) Report
> Merging [#600](https://codecov.io/gh/aquasecurity/starboard/pull/600?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) (c7a3a00) into [main](https://codecov.io/gh/aquasecurity/starboard/commit/431bdd5eb9b3afb73978bce1b9011e87d4efe3ec?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) (431bdd5) will **decrease** coverage by `26.28%`.
> The diff coverage is `0.00%`.

[![Impacted file tree graph](https://codecov.io/gh/aquasecurity/starboard/pull/600/graphs/tree.svg?width=650&height=150&src=pr&token=qqTGKAJ0Wb&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity)](https://codecov.io/gh/aquasecurity/starboard/pull/600?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity)

```diff
@@             Coverage Diff             @@
##             main     #600       +/-   ##
===========================================
- Coverage   71.61%   45.33%   -26.29%     
===========================================
  Files          57       41       -16     
  Lines        4217     3578      -639     
===========================================
- Hits         3020     1622     -1398     
- Misses        865     1861      +996     
+ Partials      332       95      -237     
```


| [Impacted Files](https://codecov.io/gh/aquasecurity/starboard/pull/600?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) | Coverage Δ | |
|---|---|---|
| [pkg/operator/controller/vulnerabilityreport.go](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL29wZXJhdG9yL2NvbnRyb2xsZXIvdnVsbmVyYWJpbGl0eXJlcG9ydC5nbw==) | `0.00% <0.00%> (-70.09%)` | :arrow_down: |
| [pkg/plugin/factory.go](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL3BsdWdpbi9mYWN0b3J5Lmdv) | `0.00% <0.00%> (-77.15%)` | :arrow_down: |
| [pkg/plugin/trivy/plugin.go](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL3BsdWdpbi90cml2eS9wbHVnaW4uZ28=) | `84.10% <ø> (-0.72%)` | :arrow_down: |
| [pkg/vulnerabilityreport/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL3Z1bG5lcmFiaWxpdHlyZXBvcnQvc2Nhbm5lci5nbw==) | `0.00% <0.00%> (-71.56%)` | :arrow_down: |
| [pkg/kubehunter/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL2t1YmVodW50ZXIvc2Nhbm5lci5nbw==) | `0.00% <0.00%> (-80.51%)` | :arrow_down: |
| [pkg/configauditreport/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL2NvbmZpZ2F1ZGl0cmVwb3J0L3NjYW5uZXIuZ28=) | `0.00% <0.00%> (-70.77%)` | :arrow_down: |
| [pkg/operator/controller/configauditreport.go](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL29wZXJhdG9yL2NvbnRyb2xsZXIvY29uZmlnYXVkaXRyZXBvcnQuZ28=) | `0.00% <0.00%> (-68.99%)` | :arrow_down: |
| [pkg/operator/controller/ciskubebenchreport.go](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity#diff-cGtnL29wZXJhdG9yL2NvbnRyb2xsZXIvY2lza3ViZWJlbmNocmVwb3J0Lmdv) | `0.00% <0.00%> (-67.03%)` | :arrow_down: |
| ... and [31 more](https://codecov.io/gh/aquasecurity/starboard/pull/600/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/600?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/600?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity). Last update [431bdd5...c7a3a00](https://codecov.io/gh/aquasecurity/starboard/pull/600?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aquasecurity).


Patch:
diff --git a/pkg/cmd/scan_vulnerabilityreports.go b/pkg/cmd/scan_vulnerabilityreports.go
index cc94a46..183b825 100644
--- a/pkg/cmd/scan_vulnerabilityreports.go
+++ b/pkg/cmd/scan_vulnerabilityreports.go
@@ -3,6 +3,7 @@ package cmd
 import (
 	"context"
 	"fmt"
+
 	"github.com/aquasecurity/starboard/pkg/plugin"
 	"github.com/aquasecurity/starboard/pkg/starboard"
 	"github.com/aquasecurity/starboard/pkg/vulnerabilityreport"
@@ -97,7 +98,7 @@ func ScanVulnerabilityReports(buildInfo starboard.BuildInfo, cf *genericclioptio
 		if err != nil {
 			return err
 		}
-		plugin, err := plugin.NewResolver().
+		plugin, pluginContext, err := plugin.NewResolver().
 			WithBuildInfo(buildInfo).
 			WithNamespace(starboard.NamespaceName).
 			WithServiceAccountName(starboard.ServiceAccountName).
@@ -107,7 +108,7 @@ func ScanVulnerabilityReports(buildInfo starboard.BuildInfo, cf *genericclioptio
 		if err != nil {
 			return err
 		}
-		scanner := vulnerabilityreport.NewScanner(kubeClientset, kubeClient, plugin, config, opts)
+		scanner := vulnerabilityreport.NewScanner(kubeClientset, kubeClient, plugin, pluginContext, config, opts)
 		reports, err := scanner.Scan(ctx, workload)
 		if err != nil {
 			return err
diff --git a/pkg/operator/controller/vulnerabilityreport.go b/pkg/operator/controller/vulnerabilityreport.go
index 85a8d45..2fe882c 100644
--- a/pkg/operator/controller/vulnerabilityreport.go
+++ b/pkg/operator/controller/vulnerabilityreport.go
@@ -37,6 +37,7 @@ type VulnerabilityReportReconciler struct {
 	kube.LogsReader
 	kube.SecretsReader
 	vulnerabilityreport.Plugin
+	starboard.PluginContext
 	vulnerabilityreport.ReadWriter
 	starboard.ConfigData
 }
@@ -211,7 +212,7 @@ func (r *VulnerabilityReportReconciler) submitScanJob(ctx context.Context, spec
 		return err
 	}
 
-	templateSpec, secrets, err := r.Plugin.GetScanJobSpec(spec, credentials)
+	templateSpec, secrets, err := r.Plugin.GetScanJobSpec(r.PluginContext, spec, credentials)
 	if err != nil {
 		return err
 	}
@@ -382,7 +383,7 @@ func (r *VulnerabilityReportReconciler) processCompleteScanJob(ctx context.Conte
 		if err != nil {
 			return fmt.Errorf("getting logs for pod %q: %w", job.Namespace+"/"+job.Name, err)
 		}
-		scanResult, err := r.Plugin.ParseVulnerabilityScanResult(containerImage, logsStream)
+		scanResult, err := r.Plugin.ParseVulnerabilityReportData(containerImage, logsStream)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/operator/operator.go b/pkg/operator/operator.go
index aac95ee..590c348 100644
--- a/pkg/operator/operator.go
+++ b/pkg/operator/operator.go
@@ -129,7 +129,7 @@ func Start(ctx context.Context, buildInfo starboard.BuildInfo, operatorConfig et
 	secretsReader := kube.NewSecretsReader(mgr.GetClient())
 
 	if operatorConfig.VulnerabilityScannerEnabled {
-		plugin, err := plugin.NewResolver().
+		plugin, pluginContext, err := plugin.NewResolver().
 			WithBuildInfo(buildInfo).
 			WithNamespace(operatorNamespace).
 			WithServiceAccountName(operatorConfig.ServiceAccount).
@@ -150,6 +150,7 @@ func Start(ctx context.Context, buildInfo starboard.BuildInfo, operatorConfig et
 			LogsReader:     logsReader,
 			SecretsReader:  secretsReader,
 			Plugin:         plugin,
+			PluginContext:  pluginContext,
 			ReadWriter:     vulnerabilityreport.NewReadWriter(mgr.GetClient()),
 		}).SetupWithManager(mgr); err != nil {
 			return fmt.Errorf("unable to setup vulnerabilityreport reconciler: %w", err)
diff --git a/pkg/plugin/aqua/plugin.go b/pkg/plugin/aqua/plugin.go
index 301a0b6..d3395bb 100644
--- a/pkg/plugin/aqua/plugin.go
+++ b/pkg/plugin/aqua/plugin.go
@@ -40,7 +40,7 @@ func NewPlugin(
 	}
 }
 
-func (s *scanner) GetScanJobSpec(spec corev1.PodSpec, _ map[string]docker.Auth) (corev1.PodSpec, []*corev1.Secret, error) {
+func (s *scanner) GetScanJobSpec(_ starboard.PluginContext, spec corev1.PodSpec, _ map[string]docker.Auth) (corev1.PodSpec, []*corev1.Secret, error) {
 	initContainerName := s.idGenerator.GenerateID()
 
 	aquaImageRef, err := s.config.GetAquaImageRef()
@@ -183,7 +183,7 @@ func (s *scanner) newScanJobContainer(podContainer corev1.Container) (corev1.Con
 	}, nil
 }
 
-func (s *scanner) ParseVulnerabilityScanResult(_ string, logsReader io.ReadCloser) (v1alpha1.VulnerabilityScanResult, error) {
+func (s *scanner) ParseVulnerabilityReportData(_ string, logsReader io.ReadCloser) (v1alpha1.VulnerabilityScanResult, error) {
 	var report v1alpha1.VulnerabilityScanResult
 	err := json.NewDecoder(logsReader).Decode(&report)
 	return report, err
diff --git a/pkg/plugin/factory.go b/pkg/plugin/factory.go
index bf4824e..b5e4a34 100644
--- a/pkg/plugin/factory.go
+++ b/pkg/plugin/factory.go
@@ -55,22 +55,30 @@ func (r *Resolver) WithClient(client client.Client) *Resolver {
 // vulnerabilityreport.Plugin for the specified starboard.ConfigData.
 //
 // Starboard currently supports Trivy scanner in Standalone and ClientServer
-// mode, and Aqua enterprise scanner.
+// mode, and Aqua Enterprise scanner.
 //
 // You could add your own scanner by implementing the
 // vulnerabilityreport.Plugin interface.
-func (r *Resolver) GetVulnerabilityPlugin() (vulnerabilityreport.Plugin, error) {
+func (r *Resolver) GetVulnerabilityPlugin() (vulnerabilityreport.Plugin, starboard.PluginContext, error) {
 	scanner, err := r.config.GetVulnerabilityReportsScanner()
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
+
+	pluginContext := starboard.NewPluginContext().
+		WithName(string(scanner)).
+		WithNamespace(r.namespace).
+		WithServiceAccountName(r.serviceAccountName).
+		WithClient(r.client).
+		Get()
+
 	switch scanner {
 	case starboard.Trivy:
-		return trivy.NewPlugin(ext.NewSystemClock(), ext.NewGoogleUUIDGenerator(), r.config), nil
+		return trivy.NewPlugin(ext.NewSystemClock(), ext.NewGoogleUUIDGenerator(), r.config), pluginContext, nil
 	case starboard.Aqua:
-		return aqua.NewPlugin(ext.NewGoogleUUIDGenerator(), r.buildInfo, r.config), nil
+		return aqua.NewPlugin(ext.NewGoogleUUIDGenerator(), r.buildInfo, r.config), pluginContext, nil
 	}
-	return nil, fmt.Errorf("unsupported vulnerability scanner plugin: %s", scanner)
+	return nil, nil, fmt.Errorf("unsupported vulnerability scanner plugin: %s", scanner)
 }
 
 // GetConfigAuditPlugin is a factory method that instantiates the
diff --git a/pkg/plugin/trivy/plugin.go b/pkg/plugin/trivy/plugin.go
index d87c64a..034ce07 100644
--- a/pkg/plugin/trivy/plugin.go
+++ b/pkg/plugin/trivy/plugin.go
@@ -63,7 +63,7 @@ func NewPlugin(clock ext.Clock, idGenerator ext.IDGenerator, config Config) vuln
 	}
 }
 
-func (s *scanner) GetScanJobSpec(spec corev1.PodSpec, credentials map[string]docker.Auth) (corev1.PodSpec, []*corev1.Secret, error) {
+func (s *scanner) GetScanJobSpec(_ starboard.PluginContext, spec corev1.PodSpec, credentials map[string]docker.Auth) (corev1.PodSpec, []*corev1.Secret, error) {
 	mode, err := s.config.GetTrivyMode()
 	if err != nil {
 		return corev1.PodSpec{}, nil, err
@@ -679,7 +679,7 @@ func (s *scanner) appendTrivyInsecureEnv(image string, env []corev1.EnvVar) ([]c
 	return env, nil
 }
 
-func (s *scanner) ParseVulnerabilityScanResult(imageRef string, logsReader io.ReadCloser) (v1alpha1.VulnerabilityScanResult, error) {
+func (s *scanner) ParseVulnerabilityReportData(imageRef string, logsReader io.ReadCloser) (v1alpha1.VulnerabilityScanResult, error) {
 	var reports []ScanReport
 	err := json.NewDecoder(logsReader).Decode(&reports)
 	if err != nil {
diff --git a/pkg/vulnerabilityreport/plugin.go b/pkg/vulnerabilityreport/plugin.go
index 79c68e4..0860ded 100644
--- a/pkg/vulnerabilityreport/plugin.go
+++ b/pkg/vulnerabilityreport/plugin.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 	"github.com/aquasecurity/starboard/pkg/docker"
+	"github.com/aquasecurity/starboard/pkg/starboard"
 	corev1 "k8s.io/api/core/v1"
 )
 
@@ -18,11 +19,11 @@ type Plugin interface {
 	// The second argument maps container names to Docker registry credentials,
 	// which can be passed to the scanner as environment variables with values
 	// set from returned secrets.
-	GetScanJobSpec(spec corev1.PodSpec, credentials map[string]docker.Auth) (
+	GetScanJobSpec(ctx starboard.PluginContext, spec corev1.PodSpec, credentials map[string]docker.Auth) (
 		corev1.PodSpec, []*corev1.Secret, error)
 
-	// ParseVulnerabilityScanResult is a callback to parse and convert logs of
+	// ParseVulnerabilityReportData is a callback to parse and convert logs of
 	// the pod controlled by the scan job to v1alpha1.VulnerabilityScanResult.
-	ParseVulnerabilityScanResult(imageRef string, logsReader io.ReadCloser) (
+	ParseVulnerabilityReportData(imageRef string, logsReader io.ReadCloser) (
 		v1alpha1.VulnerabilityScanResult, error)
 }
diff --git a/pkg/vulnerabilityreport/scanner.go b/pkg/vulnerabilityreport/scanner.go
index 492a804..fd8e9cb 100644
--- a/pkg/vulnerabilityreport/scanner.go
+++ b/pkg/vulnerabilityreport/scanner.go
@@ -25,6 +25,7 @@ type Scanner struct {
 	scheme         *runtime.Scheme
 	clientset      kubernetes.Interface
 	plugin         Plugin
+	pluginContext  starboard.PluginContext
 	objectResolver *kube.ObjectResolver
 	logsReader     kube.LogsReader
 	config         starboard.ConfigData
@@ -40,6 +41,7 @@ func NewScanner(
 	clientset kubernetes.Interface,
 	client client.Client,
 	plugin Plugin,
+	pluginContext starboard.PluginContext,
 	config starboard.ConfigData,
 	opts kube.ScannerOpts,
 ) *Scanner {
@@ -48,6 +50,7 @@ func NewScanner(
 		clientset:      clientset,
 		opts:           opts,
 		plugin:         plugin,
+		pluginContext:  pluginContext,
 		objectResolver: &kube.ObjectResolver{Client: client},
 		logsReader:     kube.NewLogsReader(clientset),
 		config:         config,
@@ -117,7 +120,7 @@ func (s *Scanner) getCredentials(ctx context.Context, spec corev1.PodSpec, ns st
 }
 
 func (s *Scanner) prepareScanJob(workload client.Object, spec corev1.PodSpec, credentials map[string]docker.Auth) (*batchv1.Job, []*corev1.Secret, error) {
-	templateSpec, secrets, err := s.plugin.GetScanJobSpec(spec, credentials)
+	templateSpec, secrets, err := s.plugin.GetScanJobSpec(s.pluginContext, spec, credentials)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -200,7 +203,10 @@ func (s *Scanner) getVulnerabilityReportsByScanJob(ctx context.Context, job *bat
 		if err != nil {
 			return nil, err
 		}
-		result, err := s.plugin.ParseVulnerabilityScanResult(containerImage, logsStream)
+		result, err := s.plugin.ParseVulnerabilityReportData(containerImage, logsStream)
+		if err != nil {
+			return nil, err
+		}
 
 		_ = logsStream.Close()
 


Test patch:
diff --git a/pkg/plugin/trivy/plugin_test.go b/pkg/plugin/trivy/plugin_test.go
index 553205d..98b1139 100644
--- a/pkg/plugin/trivy/plugin_test.go
+++ b/pkg/plugin/trivy/plugin_test.go
@@ -1357,8 +1357,13 @@ CVE-2019-1543`,
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
+			pluginContext := starboard.NewPluginContext().
+				WithName(string(starboard.Trivy)).
+				WithNamespace("starboard-ns").
+				WithServiceAccountName("starboard-sa").
+				Get()
 			instance := trivy.NewPlugin(fixedClock, ext.NewSimpleIDGenerator(), tc.config)
-			jobSpec, secrets, err := instance.GetScanJobSpec(tc.workloadSpec, nil)
+			jobSpec, secrets, err := instance.GetScanJobSpec(pluginContext, tc.workloadSpec, nil)
 			require.NoError(t, err)
 			assert.Empty(t, secrets)
 			assert.Equal(t, tc.expectedJobSpec, jobSpec)
@@ -1446,7 +1451,7 @@ var (
 	}
 )
 
-func TestScanner_ParseVulnerabilityScanResult(t *testing.T) {
+func TestScanner_ParseVulnerabilityReportData(t *testing.T) {
 	config := starboard.ConfigData{
 		"trivy.imageRef": "aquasec/trivy:0.9.1",
 	}
@@ -1506,7 +1511,7 @@ func TestScanner_ParseVulnerabilityScanResult(t *testing.T) {
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
 			instance := trivy.NewPlugin(fixedClock, ext.NewSimpleIDGenerator(), config)
-			report, err := instance.ParseVulnerabilityScanResult(tc.imageRef, io.NopCloser(strings.NewReader(tc.input)))
+			report, err := instance.ParseVulnerabilityReportData(tc.imageRef, io.NopCloser(strings.NewReader(tc.input)))
 			switch {
 			case tc.expectedError == nil:
 				require.NoError(t, err)