From 1090550950fe1aa72b435e4978e229284a024c74 Mon Sep 17 00:00:00 2001 From: Roman Kuzmin Date: Mon, 23 May 2022 19:49:03 +0400 Subject: [PATCH 1/2] Add GCR compatibility --- .../managed-registries.md | 27 +++++++- docs/vulnerability-scanning/trivy.md | 1 + pkg/plugin/trivy/plugin.go | 64 +++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/docs/vulnerability-scanning/managed-registries.md b/docs/vulnerability-scanning/managed-registries.md index 49a64058a..d72558dc1 100644 --- a/docs/vulnerability-scanning/managed-registries.md +++ b/docs/vulnerability-scanning/managed-registries.md @@ -75,4 +75,29 @@ kubectl -n starboard edit cm starboard # validate starboard config --get scanJob.podTemplateLabels -``` \ No newline at end of file +``` + +## Google Container Registry (GCR) + +You must create Google service account in your GCP console with following roles: `Artifact Registry Reader` and `Storage Object Viewer`. To make this, go to the `APIs & Services -> Credentials`, then click on `Create credentials` button and select Service account in drop-down list. Then you need to create JSON key. To make this, go to the created Service account page, and in `Keys` tab create new JSON key. + +After downloading your Service account's JSON key, you need to create `Secret` with this JSON key in your cluster with Starboard(IMPORTANT: Secret name should be `starboard-trivy-google-creds`): + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: starboard-trivy-google-creds + namespace: starboard-system +data: + google-creds.json: +``` + +After creating `Secret` you need to tell you Starboard deployment to use this credentials: + +``` +kubectl patch configmap/starboard-trivy-config \ + -n starboard-system \ + --type merge \ + -p '{"data":{"trivy.googleAppCreds":"google-creds.json"}}' +``` diff --git a/docs/vulnerability-scanning/trivy.md b/docs/vulnerability-scanning/trivy.md index f7bbc6084..debeb7ac5 100644 --- a/docs/vulnerability-scanning/trivy.md +++ b/docs/vulnerability-scanning/trivy.md @@ -104,6 +104,7 @@ EOF | `trivy.resources.requests.memory` | `100M` | The minimum amount of memory required to run Trivy scanner pod. | | `trivy.resources.limits.cpu` | `500m` | The maximum amount of CPU allowed to run Trivy scanner pod. | | `trivy.resources.limits.memory` | `500M` | The maximum amount of memory allowed to run Trivy scanner pod. | +| `trivy.googleAppCreds` | N/A | Name of the file with Google Application Credentials used in `starboard-trivy-google-creds` secrets (if defined) | | SECRET KEY | DESCRIPTION | |-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------| diff --git a/pkg/plugin/trivy/plugin.go b/pkg/plugin/trivy/plugin.go index ddf3ea196..c5402c8fc 100644 --- a/pkg/plugin/trivy/plugin.go +++ b/pkg/plugin/trivy/plugin.go @@ -44,6 +44,7 @@ const ( keyTrivySkipFiles = "trivy.skipFiles" keyTrivySkipDirs = "trivy.skipDirs" keyTrivyDBRepository = "trivy.dbRepository" + keyTrivyGoogleAppCreds = "trivy.googleAppCreds" keyTrivyServerURL = "trivy.serverURL" keyTrivyServerTokenHeader = "trivy.serverTokenHeader" @@ -134,6 +135,15 @@ func (c Config) IgnoreFileExists() bool { return ok } +func (c Config) GoogleCredsFileExists() bool { + _, ok := c.Data[keyTrivyGoogleAppCreds] + return ok +} + +func (c Config) GetGoogleCredsFile() (string, error) { + return c.GetRequiredData(keyTrivyGoogleAppCreds) +} + func (c Config) IgnoreUnfixed() bool { _, ok := c.Data[keyTrivyIgnoreUnfixed] return ok @@ -314,6 +324,8 @@ const ( ignoreFileVolumeName = "ignorefile" FsSharedVolumeName = "starboard" SharedVolumeLocationOfTrivy = "/var/starboard/trivy" + googleCredsVolumeName = "google-app-creds" + googleCredsSecretName = "starboard-trivy-google-creds" ) // In the Standalone mode there is the init container responsible for @@ -456,6 +468,23 @@ func (p *plugin) getPodSpecForStandaloneMode(ctx starboard.PluginContext, config }, } + if config.GoogleCredsFileExists() { + volumes = append(volumes, corev1.Volume{ + Name: googleCredsVolumeName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: googleCredsSecretName, + }, + }, + }) + + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: googleCredsVolumeName, + ReadOnly: true, + MountPath: "/tmp/google-creds", + }) + } + if config.IgnoreFileExists() { volumes = append(volumes, corev1.Volume{ Name: ignoreFileVolumeName, @@ -582,6 +611,15 @@ func (p *plugin) getPodSpecForStandaloneMode(ctx starboard.PluginContext, config }, } + if config.GoogleCredsFileExists() { + googleCredsEnv, _ := config.GetGoogleCredsFile() + googleCredsEnv = "/tmp/google-creds/" + googleCredsEnv + env = append(env, corev1.EnvVar{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", + Value: googleCredsEnv, + }) + } + if config.IgnoreFileExists() { env = append(env, corev1.EnvVar{ Name: "TRIVY_IGNOREFILE", @@ -881,6 +919,15 @@ func (p *plugin) getPodSpecForClientServerMode(ctx starboard.PluginContext, conf }) } + if config.GoogleCredsFileExists() { + googleCredsEnv, _ := config.GetGoogleCredsFile() + googleCredsEnv = "/tmp/google-creds/" + googleCredsEnv + env = append(env, corev1.EnvVar{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", + Value: googleCredsEnv, + }) + } + env, err = p.appendTrivyInsecureEnv(config, container.Image, env) if err != nil { return corev1.PodSpec{}, nil, err @@ -898,6 +945,23 @@ func (p *plugin) getPodSpecForClientServerMode(ctx starboard.PluginContext, conf }) } + if config.GoogleCredsFileExists() { + volumes = append(volumes, corev1.Volume{ + Name: googleCredsVolumeName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: googleCredsSecretName, + }, + }, + }) + + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: googleCredsVolumeName, + ReadOnly: true, + MountPath: "/tmp/google-creds", + }) + } + if config.IgnoreFileExists() { volumes = []corev1.Volume{ { From 791530fa6fd6384ba8625a1ace20a2b7f61fad29 Mon Sep 17 00:00:00 2001 From: Roman Kuzmin Date: Mon, 23 May 2022 21:46:12 +0400 Subject: [PATCH 2/2] Add test for GCR credentials --- pkg/plugin/trivy/plugin_test.go | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/pkg/plugin/trivy/plugin_test.go b/pkg/plugin/trivy/plugin_test.go index e17c7a344..f38e13ab4 100644 --- a/pkg/plugin/trivy/plugin_test.go +++ b/pkg/plugin/trivy/plugin_test.go @@ -437,6 +437,41 @@ func TestConfig_GetMirrors(t *testing.T) { } } +func TestConfig_GoogleCredsFileExists(t *testing.T) { + testCases := []struct { + name string + configData trivy.Config + expectedOutput bool + }{ + { + name: "Should return false", + configData: trivy.Config{PluginConfig: starboard.PluginConfig{ + Data: map[string]string{ + "foo": "bar", + }, + }}, + expectedOutput: false, + }, + { + name: "Should return true", + configData: trivy.Config{PluginConfig: starboard.PluginConfig{ + Data: map[string]string{ + "foo": "bar", + "trivy.googleAppCreds": "google-creds.json", + }, + }}, + expectedOutput: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + exists := tc.configData.GoogleCredsFileExists() + assert.Equal(t, tc.expectedOutput, exists) + }) + } +} + func TestPlugin_Init(t *testing.T) { t.Run("Should create the default config", func(t *testing.T) {