Repository: aquasecurity/starboard
Pull request #252 (2020-12-02 13:47:35)

feat(vulnerabilityreports): Use primary URLs returned by Trivy v0.14.0
Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/252?src=pr&el=h1) Report
> Merging [#252](https://codecov.io/gh/aquasecurity/starboard/pull/252?src=pr&el=desc) (c0190d3) into [master](https://codecov.io/gh/aquasecurity/starboard/commit/8b2ac0843fc7779df0233bb33cfdb16fdafcb981?el=desc) (8b2ac08) will **decrease** coverage by `43.39%`.
> The diff coverage is `70.37%`.

[![Impacted file tree graph](https://codecov.io/gh/aquasecurity/starboard/pull/252/graphs/tree.svg?width=650&height=150&src=pr&token=qqTGKAJ0Wb)](https://codecov.io/gh/aquasecurity/starboard/pull/252?src=pr&el=tree)

```diff
@@             Coverage Diff             @@
##           master     #252       +/-   ##
===========================================
- Coverage   62.67%   19.27%   -43.40%     
===========================================
  Files          56       50        -6     
  Lines        2489     2158      -331     
===========================================
- Hits         1560      416     -1144     
- Misses        730     1705      +975     
+ Partials      199       37      -162     
```


| [Impacted Files](https://codecov.io/gh/aquasecurity/starboard/pull/252?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/find/vulnerabilities/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL2ZpbmQvdnVsbmVyYWJpbGl0aWVzL3NjYW5uZXIuZ28=) | `0.00% <0.00%> (-74.26%)` | :arrow_down: |
| [pkg/trivy/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL3RyaXZ5L3NjYW5uZXIuZ28=) | `0.00% <0.00%> (-73.42%)` | :arrow_down: |
| [pkg/trivy/converter.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL3RyaXZ5L2NvbnZlcnRlci5nbw==) | `83.33% <80.00%> (-10.32%)` | :arrow_down: |
| [pkg/starboard/config.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL3N0YXJib2FyZC9jb25maWcuZ28=) | `72.41% <100.00%> (ø)` | |
| [pkg/cmd/get.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL2NtZC9nZXQuZ28=) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/find.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL2NtZC9maW5kLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/scan.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL2NtZC9zY2FuLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/polaris.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL2NtZC9wb2xhcmlzLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/version.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL2NtZC92ZXJzaW9uLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/kube\_bench.go](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree#diff-cGtnL2NtZC9rdWJlX2JlbmNoLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| ... and [32 more](https://codecov.io/gh/aquasecurity/starboard/pull/252/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/252?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/252?src=pr&el=footer). Last update [8b2ac08...c0190d3](https://codecov.io/gh/aquasecurity/starboard/pull/252?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/README.md b/README.md
index 9f049ac..4fa9185 100644
--- a/README.md
+++ b/README.md
@@ -271,7 +271,7 @@ The following table lists available configuration parameters.
 | `trivy.httpProxy`     | N/A                                                    | The HTTP proxy used by Trivy to download the vulnerabilities database from GitHub. Only applicable if Trivy runs in the `Standalone` mode. |
 | `trivy.githubToken`   | N/A                                                    | The GitHub personal access token used by Trivy to download the vulnerabilities database from GitHub. Only applicable if Trivy runs in the `Standalone` mode. |
 | `trivy.severity`      | `UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL`                     | A comma separated list of severity levels reported by Trivy |
-| `trivy.imageRef`      | `docker.io/aquasec/trivy:0.12.0`                       | Trivy image reference |
+| `trivy.imageRef`      | `docker.io/aquasec/trivy:0.14.0`                       | Trivy image reference |
 | `trivy.mode`          | `Standalone`                                           | Trivy client mode. Either `Standalone` or `ClientServer`. |
 | `trivy.serverURL`     | `http://trivy-server.trivy-server:4954`                | The endpoint URL of the Trivy server. This parameter is required when Trivy runs in the `ClientServer` mode. |
 | `polaris.config.yaml` | [Check the default value here][default-polaris-config] | Polaris configuration file |
diff --git a/deploy/init/03-starboard.cm.yaml b/deploy/init/03-starboard.cm.yaml
index b3ad50c..8b23170 100644
--- a/deploy/init/03-starboard.cm.yaml
+++ b/deploy/init/03-starboard.cm.yaml
@@ -7,7 +7,7 @@ metadata:
   namespace: starboard
 data:
   trivy.severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
-  trivy.imageRef: docker.io/aquasec/trivy:0.12.0
+  trivy.imageRef: docker.io/aquasec/trivy:0.14.0
   trivy.mode: Standalone
   trivy.serverURL: http://trivy-server.trivy-server:4954
   kube-bench.imageRef: docker.io/aquasec/kube-bench:0.4.0
diff --git a/deploy/trivy-server/03-trivy-server.deployment.yaml b/deploy/trivy-server/03-trivy-server.deployment.yaml
index 4e93be1..af34def 100644
--- a/deploy/trivy-server/03-trivy-server.deployment.yaml
+++ b/deploy/trivy-server/03-trivy-server.deployment.yaml
@@ -23,7 +23,7 @@ spec:
           emptyDir: {}
       containers:
         - name: trivy-server
-          image: docker.io/aquasec/trivy:0.12.0
+          image: docker.io/aquasec/trivy:0.14.0
           command:
             - trivy
             - server
diff --git a/deploy/trivy-server/README.md b/deploy/trivy-server/README.md
index 7e4451f..fe634ad 100644
--- a/deploy/trivy-server/README.md
+++ b/deploy/trivy-server/README.md
@@ -10,7 +10,7 @@ $ kubectl apply -f deploy/trivy-server
 ```
 
 ```
-$ kubectl run trivy-client -it --rm --image aquasec/trivy:0.12.0 --command -- sh
+$ kubectl run trivy-client -it --rm --image aquasec/trivy:0.14.0 --command -- sh
 / # trivy client --format json --remote http://trivy-server.trivy-server:4954 wordpress:4.9
 / # trivy client --format json --remote http://trivy-server.trivy-server:4954 wordpress:5.5
 ```
diff --git a/pkg/find/vulnerabilities/scanner.go b/pkg/find/vulnerabilities/scanner.go
index 09ee757..c0d2bc0 100644
--- a/pkg/find/vulnerabilities/scanner.go
+++ b/pkg/find/vulnerabilities/scanner.go
@@ -40,7 +40,7 @@ func NewScanner(scheme *runtime.Scheme, config starboard.TrivyConfig, opts kube.
 		opts:        opts,
 		clientset:   clientset,
 		pods:        pod.NewPodManager(clientset),
-		converter:   trivy.DefaultConverter,
+		converter:   trivy.NewConverter(config),
 		idGenerator: idGenerator,
 		delegate:    trivy.NewScanner(idGenerator, config),
 	}
@@ -173,7 +173,7 @@ func (s *Scanner) GetVulnerabilityReportsByScanJob(ctx context.Context, job *bat
 		if err != nil {
 			return nil, err
 		}
-		result, err := s.converter.Convert(s.config, containerImages[c.Name], logReader)
+		result, err := s.converter.Convert(containerImages[c.Name], logReader)
 
 		report, err := vulnerabilityreport.NewBuilder(s.scheme).
 			Owner(owner).
diff --git a/pkg/starboard/config.go b/pkg/starboard/config.go
index f51e92b..feb4574 100644
--- a/pkg/starboard/config.go
+++ b/pkg/starboard/config.go
@@ -251,8 +251,8 @@ type ConfigManager interface {
 func GetDefaultConfig() ConfigData {
 	return map[string]string{
 		"trivy.severity":      "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL",
-		"trivy.imageRef":      "docker.io/aquasec/trivy:0.12.0",
-		"trivy.mode":          "Standalone",
+		"trivy.imageRef":      "docker.io/aquasec/trivy:0.14.0",
+		"trivy.mode":          string(Standalone),
 		"trivy.serverURL":     "http://trivy-server.trivy-server:4954",
 		"kube-bench.imageRef": "docker.io/aquasec/kube-bench:0.4.0",
 		"polaris.config.yaml": polarisConfigYAML,
@@ -263,7 +263,7 @@ func (c ConfigData) GetTrivyImageRef() string {
 	if imageRef, ok := c["trivy.imageRef"]; ok {
 		return imageRef
 	}
-	return "docker.io/aquasec/trivy:0.12.0"
+	return "docker.io/aquasec/trivy:0.14.0"
 }
 
 func (c ConfigData) GetTrivyMode() TrivyMode {
diff --git a/pkg/trivy/converter.go b/pkg/trivy/converter.go
index 45072cb..61edf94 100644
--- a/pkg/trivy/converter.go
+++ b/pkg/trivy/converter.go
@@ -9,7 +9,7 @@ import (
 
 	"github.com/aquasecurity/starboard/pkg/starboard"
 
-	starboardv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 	"github.com/google/go-containerregistry/pkg/name"
 )
 
@@ -18,58 +18,59 @@ import (
 // Convert converts the vulnerabilities model used by Trivy
 // to a generic model defined by the Custom Security Resource Specification.
 type Converter interface {
-	Convert(config starboard.TrivyConfig, imageRef string, reader io.Reader) (starboardv1alpha1.VulnerabilityScanResult, error)
+	Convert(imageRef string, reader io.Reader) (v1alpha1.VulnerabilityScanResult, error)
 }
 
 type converter struct {
+	config starboard.TrivyConfig
 }
 
-var DefaultConverter = NewConverter()
-
-func NewConverter() Converter {
-	return &converter{}
+func NewConverter(config starboard.TrivyConfig) Converter {
+	return &converter{
+		config: config,
+	}
 }
 
-func (c *converter) Convert(config starboard.TrivyConfig, imageRef string, reader io.Reader) (report starboardv1alpha1.VulnerabilityScanResult, err error) {
+func (c *converter) Convert(imageRef string, reader io.Reader) (v1alpha1.VulnerabilityScanResult, error) {
 	var scanReports []ScanReport
-	err = json.NewDecoder(reader).Decode(&scanReports)
+	err := json.NewDecoder(reader).Decode(&scanReports)
 	if err != nil {
-		return
+		return v1alpha1.VulnerabilityScanResult{}, err
 	}
-	return c.convert(config, imageRef, scanReports)
+	return c.convert(imageRef, scanReports)
 }
 
-func (c *converter) convert(config starboard.TrivyConfig, imageRef string, reports []ScanReport) (starboardv1alpha1.VulnerabilityScanResult, error) {
-	vulnerabilities := make([]starboardv1alpha1.Vulnerability, 0)
+func (c *converter) convert(imageRef string, reports []ScanReport) (v1alpha1.VulnerabilityScanResult, error) {
+	vulnerabilities := make([]v1alpha1.Vulnerability, 0)
 
 	for _, report := range reports {
 		for _, sr := range report.Vulnerabilities {
-			vulnerabilities = append(vulnerabilities, starboardv1alpha1.Vulnerability{
+			vulnerabilities = append(vulnerabilities, v1alpha1.Vulnerability{
 				VulnerabilityID:  sr.VulnerabilityID,
 				Resource:         sr.PkgName,
 				InstalledVersion: sr.InstalledVersion,
 				FixedVersion:     sr.FixedVersion,
 				Severity:         sr.Severity,
 				Title:            sr.Title,
-				Description:      sr.Description,
-				Links:            c.toLinks(sr.References),
+				PrimaryLink:      sr.PrimaryURL,
+				Links:            []string{},
 			})
 		}
 	}
 
 	registry, artifact, err := c.parseImageRef(imageRef)
 	if err != nil {
-		return starboardv1alpha1.VulnerabilityScanResult{}, err
+		return v1alpha1.VulnerabilityScanResult{}, err
 	}
 
-	version, err := starboard.GetVersionFromImageRef(config.GetTrivyImageRef())
+	version, err := starboard.GetVersionFromImageRef(c.config.GetTrivyImageRef())
 	if err != nil {
-		return starboardv1alpha1.VulnerabilityScanResult{}, err
+		return v1alpha1.VulnerabilityScanResult{}, err
 	}
 
-	return starboardv1alpha1.VulnerabilityScanResult{
+	return v1alpha1.VulnerabilityScanResult{
 		UpdateTimestamp: metav1.NewTime(time.Now()),
-		Scanner: starboardv1alpha1.Scanner{
+		Scanner: v1alpha1.Scanner{
 			Name:    "Trivy",
 			Vendor:  "Aqua Security",
 			Version: version,
@@ -81,23 +82,16 @@ func (c *converter) convert(config starboard.TrivyConfig, imageRef string, repor
 	}, nil
 }
 
-func (c *converter) toLinks(references []string) []string {
-	if references == nil {
-		return []string{}
-	}
-	return references
-}
-
-func (c *converter) toSummary(vulnerabilities []starboardv1alpha1.Vulnerability) (vs starboardv1alpha1.VulnerabilitySummary) {
+func (c *converter) toSummary(vulnerabilities []v1alpha1.Vulnerability) (vs v1alpha1.VulnerabilitySummary) {
 	for _, v := range vulnerabilities {
 		switch v.Severity {
-		case starboardv1alpha1.SeverityCritical:
+		case v1alpha1.SeverityCritical:
 			vs.CriticalCount++
-		case starboardv1alpha1.SeverityHigh:
+		case v1alpha1.SeverityHigh:
 			vs.HighCount++
-		case starboardv1alpha1.SeverityMedium:
+		case v1alpha1.SeverityMedium:
 			vs.MediumCount++
-		case starboardv1alpha1.SeverityLow:
+		case v1alpha1.SeverityLow:
 			vs.LowCount++
 		default:
 			vs.UnknownCount++
@@ -106,15 +100,15 @@ func (c *converter) toSummary(vulnerabilities []starboardv1alpha1.Vulnerability)
 	return
 }
 
-func (c *converter) parseImageRef(imageRef string) (starboardv1alpha1.Registry, starboardv1alpha1.Artifact, error) {
+func (c *converter) parseImageRef(imageRef string) (v1alpha1.Registry, v1alpha1.Artifact, error) {
 	ref, err := name.ParseReference(imageRef)
 	if err != nil {
-		return starboardv1alpha1.Registry{}, starboardv1alpha1.Artifact{}, err
+		return v1alpha1.Registry{}, v1alpha1.Artifact{}, err
 	}
-	registry := starboardv1alpha1.Registry{
+	registry := v1alpha1.Registry{
 		Server: ref.Context().RegistryStr(),
 	}
-	artifact := starboardv1alpha1.Artifact{
+	artifact := v1alpha1.Artifact{
 		Repository: ref.Context().RepositoryStr(),
 	}
 	switch t := ref.(type) {
diff --git a/pkg/trivy/model.go b/pkg/trivy/model.go
index ad39847..94ed52e 100644
--- a/pkg/trivy/model.go
+++ b/pkg/trivy/model.go
@@ -1,7 +1,7 @@
 package trivy
 
 import (
-	sec "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 )
 
 type ScanReport struct {
@@ -10,13 +10,19 @@ type ScanReport struct {
 }
 
 type Vulnerability struct {
-	VulnerabilityID  string       `json:"VulnerabilityID"`
-	PkgName          string       `json:"PkgName"`
-	InstalledVersion string       `json:"InstalledVersion"`
-	FixedVersion     string       `json:"FixedVersion"`
-	Title            string       `json:"Title"`
-	Description      string       `json:"Description"`
-	Severity         sec.Severity `json:"Severity"`
-	LayerID          string       `json:"LayerID"`
-	References       []string     `json:"References"`
+	VulnerabilityID  string            `json:"VulnerabilityID"`
+	PkgName          string            `json:"PkgName"`
+	InstalledVersion string            `json:"InstalledVersion"`
+	FixedVersion     string            `json:"FixedVersion"`
+	Title            string            `json:"Title"`
+	Description      string            `json:"Description"`
+	Severity         v1alpha1.Severity `json:"Severity"`
+	Layer            Layer             `json:"Layer"`
+	PrimaryURL       string            `json:"PrimaryURL"`
+	References       []string          `json:"References"`
+}
+
+type Layer struct {
+	Digest string `json:"Digest"`
+	DiffID string `json:"DiffID"`
 }
diff --git a/pkg/trivy/scanner.go b/pkg/trivy/scanner.go
index 8e44f67..a6f7b66 100644
--- a/pkg/trivy/scanner.go
+++ b/pkg/trivy/scanner.go
@@ -32,6 +32,7 @@ var (
 type trivyScanner struct {
 	idGenerator ext.IDGenerator
 	config      starboard.TrivyConfig
+	converter   Converter
 }
 
 // NewScanner constructs a new vulnerabilityreport.Scanner, which is using an official
@@ -46,6 +47,7 @@ func NewScanner(idGenerator ext.IDGenerator, config starboard.TrivyConfig) vulne
 	return &trivyScanner{
 		idGenerator: idGenerator,
 		config:      config,
+		converter:   NewConverter(config),
 	}
 }
 
@@ -246,7 +248,7 @@ func (s *trivyScanner) getPodSpecForClientServerMode(spec corev1.PodSpec) (corev
 }
 
 func (s *trivyScanner) ParseVulnerabilityScanResult(imageRef string, logsReader io.ReadCloser) (v1alpha1.VulnerabilityScanResult, error) {
-	result, err := DefaultConverter.Convert(s.config, imageRef, logsReader)
+	result, err := s.converter.Convert(imageRef, logsReader)
 	if err != nil {
 		return v1alpha1.VulnerabilityScanResult{}, err
 	}


Test patch:
diff --git a/itest/starboard/starboard_cli_test.go b/itest/starboard/starboard_cli_test.go
index ba0c95e..483ed89 100644
--- a/itest/starboard/starboard_cli_test.go
+++ b/itest/starboard/starboard_cli_test.go
@@ -225,7 +225,7 @@ var _ = Describe("Starboard CLI", func() {
 							"Scanner": Equal(v1alpha1.Scanner{
 								Name:    "Trivy",
 								Vendor:  "Aqua Security",
-								Version: "0.12.0",
+								Version: "0.14.0",
 							}),
 						}),
 					}),
@@ -290,7 +290,7 @@ var _ = Describe("Starboard CLI", func() {
 							"Scanner": Equal(v1alpha1.Scanner{
 								Name:    "Trivy",
 								Vendor:  "Aqua Security",
-								Version: "0.12.0",
+								Version: "0.14.0",
 							}),
 						}),
 					}),
@@ -313,7 +313,7 @@ var _ = Describe("Starboard CLI", func() {
 							"Scanner": Equal(v1alpha1.Scanner{
 								Name:    "Trivy",
 								Vendor:  "Aqua Security",
-								Version: "0.12.0",
+								Version: "0.14.0",
 							}),
 						}),
 					}),
@@ -396,7 +396,7 @@ var _ = Describe("Starboard CLI", func() {
 							"Scanner": Equal(v1alpha1.Scanner{
 								Name:    "Trivy",
 								Vendor:  "Aqua Security",
-								Version: "0.12.0",
+								Version: "0.14.0",
 							}),
 						}),
 					}),
@@ -491,7 +491,7 @@ var _ = Describe("Starboard CLI", func() {
 							"Scanner": Equal(v1alpha1.Scanner{
 								Name:    "Trivy",
 								Vendor:  "Aqua Security",
-								Version: "0.12.0",
+								Version: "0.14.0",
 							}),
 						}),
 					}),
@@ -582,7 +582,7 @@ var _ = Describe("Starboard CLI", func() {
 							"Scanner": Equal(v1alpha1.Scanner{
 								Name:    "Trivy",
 								Vendor:  "Aqua Security",
-								Version: "0.12.0",
+								Version: "0.14.0",
 							}),
 						}),
 					}),
@@ -673,7 +673,7 @@ var _ = Describe("Starboard CLI", func() {
 							"Scanner": Equal(v1alpha1.Scanner{
 								Name:    "Trivy",
 								Vendor:  "Aqua Security",
-								Version: "0.12.0",
+								Version: "0.14.0",
 							}),
 						}),
 					}),
@@ -716,7 +716,7 @@ var _ = Describe("Starboard CLI", func() {
 					Scanner: v1alpha1.Scanner{
 						Name:    "Trivy",
 						Vendor:  "Aqua Security",
-						Version: "0.12.0",
+						Version: "0.14.0",
 					},
 					Registry: v1alpha1.Registry{
 						Server: "index.docker.io",
diff --git a/pkg/starboard/config_test.go b/pkg/starboard/config_test.go
index debfb51..9e3b131 100644
--- a/pkg/starboard/config_test.go
+++ b/pkg/starboard/config_test.go
@@ -59,7 +59,7 @@ func TestConfigData_GetTrivyImageRef(t *testing.T) {
 		{
 			name:             "Should return default image reference",
 			configData:       starboard.ConfigData{},
-			expectedImageRef: "docker.io/aquasec/trivy:0.12.0",
+			expectedImageRef: "docker.io/aquasec/trivy:0.14.0",
 		},
 		{
 			name: "Should return image reference from config data",
diff --git a/pkg/trivy/converter_test.go b/pkg/trivy/converter_test.go
index 16f7e64..206f7a6 100644
--- a/pkg/trivy/converter_test.go
+++ b/pkg/trivy/converter_test.go
@@ -12,85 +12,84 @@ import (
 
 	"github.com/aquasecurity/starboard/pkg/starboard"
 
-	starboardv1alpha1 "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 var (
-	sampleReportAsString = `[
-	{
+	sampleReportAsString = `[{
 		"Target": "alpine:3.10.2 (alpine 3.10.2)",
 		"Type": "alpine",
 		"Vulnerabilities": [
-		{
-			"VulnerabilityID": "CVE-2019-1549",
-			"PkgName": "openssl",
-			"InstalledVersion": "1.1.1c-r0",
-			"FixedVersion": "1.1.1d-r0",
-			"Title": "openssl: information disclosure in fork()",
-			"Severity": "MEDIUM",
-			"References": [
-				"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549"
-		]
-		},
-		{
-			"VulnerabilityID": "CVE-2019-1547",
-			"PkgName": "openssl",
-			"InstalledVersion": "1.1.1c-r0",
-			"FixedVersion": "1.1.1d-r0",
-			"Title": "openssl: side-channel weak encryption vulnerability",
-			"Severity": "LOW",
-			"References": [
-				"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547"
+			{
+				"VulnerabilityID": "CVE-2019-1549",
+				"PkgName": "openssl",
+				"InstalledVersion": "1.1.1c-r0",
+				"FixedVersion": "1.1.1d-r0",
+				"Title": "openssl: information disclosure in fork()",
+				"Description": "Usually this long long description of CVE-2019-1549",
+				"Severity": "MEDIUM",
+				"PrimaryURL": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549",
+				"References": [
+					"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549"
+				]
+			},
+			{
+				"VulnerabilityID": "CVE-2019-1547",
+				"PkgName": "openssl",
+				"InstalledVersion": "1.1.1c-r0",
+				"FixedVersion": "1.1.1d-r0",
+				"Title": "openssl: side-channel weak encryption vulnerability",
+				"Severity": "LOW",
+				"PrimaryURL": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547",
+				"References": [
+					"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547"
+				]
+			}
 		]
-		}
-	]
-	}
-]`
+	}]`
 
-	sampleReport = starboardv1alpha1.VulnerabilityScanResult{
-		Scanner: starboardv1alpha1.Scanner{
+	sampleReport = v1alpha1.VulnerabilityScanResult{
+		Scanner: v1alpha1.Scanner{
 			Name:    "Trivy",
 			Vendor:  "Aqua Security",
 			Version: "0.9.1",
 		},
-		Registry: starboardv1alpha1.Registry{
+		Registry: v1alpha1.Registry{
 			Server: "index.docker.io",
 		},
-		Artifact: starboardv1alpha1.Artifact{
+		Artifact: v1alpha1.Artifact{
 			Repository: "library/alpine",
 			Tag:        "3.10.2",
 		},
-		Summary: starboardv1alpha1.VulnerabilitySummary{
+		Summary: v1alpha1.VulnerabilitySummary{
 			CriticalCount: 0,
 			MediumCount:   1,
 			LowCount:      1,
 			NoneCount:     0,
 			UnknownCount:  0,
 		},
-		Vulnerabilities: []starboardv1alpha1.Vulnerability{
+		Vulnerabilities: []v1alpha1.Vulnerability{
 			{
 				VulnerabilityID:  "CVE-2019-1549",
 				Resource:         "openssl",
 				InstalledVersion: "1.1.1c-r0",
 				FixedVersion:     "1.1.1d-r0",
-				Severity:         starboardv1alpha1.SeverityMedium,
+				Severity:         v1alpha1.SeverityMedium,
 				Title:            "openssl: information disclosure in fork()",
-				Links: []string{
-					"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549",
-				},
+				PrimaryLink:      "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549",
+				Links:            []string{},
 			},
 			{
 				VulnerabilityID:  "CVE-2019-1547",
 				Resource:         "openssl",
 				InstalledVersion: "1.1.1c-r0",
 				FixedVersion:     "1.1.1d-r0",
-				Severity:         starboardv1alpha1.SeverityLow,
+				Severity:         v1alpha1.SeverityLow,
 				Title:            "openssl: side-channel weak encryption vulnerability",
-				Links: []string{
-					"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547",
-				},
+				PrimaryLink:      "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547",
+				Links:            []string{},
 			},
 		},
 	}
@@ -106,7 +105,7 @@ func TestConverter_Convert(t *testing.T) {
 		imageRef       string
 		input          string
 		expectedError  error
-		expectedReport starboardv1alpha1.VulnerabilityScanResult
+		expectedReport v1alpha1.VulnerabilityScanResult
 	}{
 		{
 			name:           "Should convert vulnerability report in JSON format when input is quiet",
@@ -120,20 +119,20 @@ func TestConverter_Convert(t *testing.T) {
 			imageRef:      "core.harbor.domain/library/nginx@sha256:d20aa6d1cae56fd17cd458f4807e0de462caf2336f0b70b5eeb69fcaaf30dd9c",
 			input:         `null`,
 			expectedError: nil,
-			expectedReport: starboardv1alpha1.VulnerabilityScanResult{
-				Scanner: starboardv1alpha1.Scanner{
+			expectedReport: v1alpha1.VulnerabilityScanResult{
+				Scanner: v1alpha1.Scanner{
 					Name:    "Trivy",
 					Vendor:  "Aqua Security",
 					Version: "0.9.1",
 				},
-				Registry: starboardv1alpha1.Registry{
+				Registry: v1alpha1.Registry{
 					Server: "core.harbor.domain",
 				},
-				Artifact: starboardv1alpha1.Artifact{
+				Artifact: v1alpha1.Artifact{
 					Repository: "library/nginx",
 					Digest:     "sha256:d20aa6d1cae56fd17cd458f4807e0de462caf2336f0b70b5eeb69fcaaf30dd9c",
 				},
-				Summary: starboardv1alpha1.VulnerabilitySummary{
+				Summary: v1alpha1.VulnerabilitySummary{
 					CriticalCount: 0,
 					HighCount:     0,
 					MediumCount:   0,
@@ -141,7 +140,7 @@ func TestConverter_Convert(t *testing.T) {
 					NoneCount:     0,
 					UnknownCount:  0,
 				},
-				Vulnerabilities: []starboardv1alpha1.Vulnerability{},
+				Vulnerabilities: []v1alpha1.Vulnerability{},
 			},
 		},
 		{
@@ -154,7 +153,7 @@ func TestConverter_Convert(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			report, err := trivy.NewConverter().Convert(config, tc.imageRef, strings.NewReader(tc.input))
+			report, err := trivy.NewConverter(config).Convert(tc.imageRef, strings.NewReader(tc.input))
 			fakeTime := metav1.NewTime(time.Now())
 			report.UpdateTimestamp = fakeTime
 			tc.expectedReport.UpdateTimestamp = fakeTime