Skip to content

Commit

Permalink
Add Vulnerability scanning report to the summaryDetails section (kube…
Browse files Browse the repository at this point in the history
…scape#1615)

* Add Vulnerability scanning report to the summaryDetails section

Signed-off-by: Alfredo Garcia <algarcia@vmware.com>

* Updating the opa-utils dependency version

Signed-off-by: Alfredo Garcia <algarcia@vmware.com>

---------

Signed-off-by: Alfredo Garcia <algarcia@vmware.com>
  • Loading branch information
agarcia-oss authored Mar 1, 2024
1 parent bc33f10 commit fad8f2b
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 9 deletions.
95 changes: 90 additions & 5 deletions core/pkg/resultshandling/printer/v2/jsonprinter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ import (
"path/filepath"
"strings"

"github.com/anchore/clio"
"github.com/anchore/grype/grype/presenter"
"github.com/anchore/grype/grype/presenter/models"
logger "github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
"github.com/kubescape/kubescape/v3/core/cautils"
"github.com/kubescape/kubescape/v3/core/pkg/resultshandling/printer"
"github.com/kubescape/kubescape/v3/core/pkg/resultshandling/printer/v2/prettyprinter/tableprinter/imageprinter"
"github.com/kubescape/opa-utils/reporthandling/results/v1/reportsummary"
"k8s.io/utils/strings/slices"
)

const (
Expand Down Expand Up @@ -54,11 +58,41 @@ func (jp *JsonPrinter) Score(score float32) {
fmt.Fprintf(os.Stderr, "\nOverall compliance-score (100- Excellent, 0- All failed): %d\n", cautils.Float32ToInt(score))

}
func (jp *JsonPrinter) convertToImageScanSummary(imageScanData []cautils.ImageScanData) (*imageprinter.ImageScanSummary, error) {
imageScanSummary := imageprinter.ImageScanSummary{
CVEs: []imageprinter.CVE{},
PackageScores: map[string]*imageprinter.PackageScore{},
MapsSeverityToSummary: map[string]*imageprinter.SeveritySummary{},
}

for i := range imageScanData {
if !slices.Contains(imageScanSummary.Images, imageScanData[i].Image) {
imageScanSummary.Images = append(imageScanSummary.Images, imageScanData[i].Image)
}

presenterConfig := imageScanData[i].PresenterConfig
doc, err := models.NewDocument(clio.Identification{}, presenterConfig.Packages, presenterConfig.Context, presenterConfig.Matches, presenterConfig.IgnoredMatches, presenterConfig.MetadataProvider, nil, presenterConfig.DBStatus)
if err != nil {
logger.L().Error(fmt.Sprintf("failed to create document for image: %v", imageScanData[i].Image), helpers.Error(err))
continue
}

CVEs := extractCVEs(doc.Matches)
imageScanSummary.CVEs = append(imageScanSummary.CVEs, CVEs...)

setPkgNameToScoreMap(doc.Matches, imageScanSummary.PackageScores)

setSeverityToSummaryMap(CVEs, imageScanSummary.MapsSeverityToSummary)
}

return &imageScanSummary, nil
}

func (jp *JsonPrinter) ActionPrint(ctx context.Context, opaSessionObj *cautils.OPASessionObj, imageScanData []cautils.ImageScanData) {
var err error

if opaSessionObj != nil {
err = printConfigurationsScanning(opaSessionObj, ctx, jp)
err = printConfigurationsScanning(opaSessionObj, ctx, imageScanData, jp)
} else if imageScanData != nil {
err = jp.PrintImageScan(ctx, imageScanData[0].PresenterConfig)
} else {
Expand All @@ -73,16 +107,67 @@ func (jp *JsonPrinter) ActionPrint(ctx context.Context, opaSessionObj *cautils.O
printer.LogOutputFile(jp.writer.Name())
}

func printConfigurationsScanning(opaSessionObj *cautils.OPASessionObj, ctx context.Context, jp *JsonPrinter) error {
r, err := json.Marshal(FinalizeResults(opaSessionObj))
if err != nil {
return err
func printConfigurationsScanning(opaSessionObj *cautils.OPASessionObj, ctx context.Context, imageScanData []cautils.ImageScanData, jp *JsonPrinter) error {

if imageScanData != nil {
imageScanSummary, err := jp.convertToImageScanSummary(imageScanData)
if err != nil {
logger.L().Error("failed to convert to image scan summary", helpers.Error(err))
return err
}
opaSessionObj.Report.SummaryDetails.Vulnerabilities.MapsSeverityToSummary = convertToReportSummary(imageScanSummary.MapsSeverityToSummary)
opaSessionObj.Report.SummaryDetails.Vulnerabilities.CVESummary = convertToCVESummary(imageScanSummary.CVEs)
opaSessionObj.Report.SummaryDetails.Vulnerabilities.PackageScores = convertToPackageScores(imageScanSummary.PackageScores)
opaSessionObj.Report.SummaryDetails.Vulnerabilities.Images = imageScanSummary.Images
}

r, err := json.Marshal(FinalizeResults(opaSessionObj))
_, err = jp.writer.Write(r)

return err
}

func convertToPackageScores(packageScores map[string]*imageprinter.PackageScore) map[string]*reportsummary.PackageSummary {
convertedPackageScores := make(map[string]*reportsummary.PackageSummary)
for pkg, score := range packageScores {
convertedPackageScores[pkg] = &reportsummary.PackageSummary{
Name: score.Name,
Version: score.Version,
Score: score.Score,
MapSeverityToCVEsNumber: score.MapSeverityToCVEsNumber,
}
}
return convertedPackageScores
}

func convertToCVESummary(cves []imageprinter.CVE) []reportsummary.CVESummary {
cveSummary := make([]reportsummary.CVESummary, len(cves))
i := 0
for _, cve := range cves {
var a reportsummary.CVESummary
a.Severity = cve.Severity
a.ID = cve.ID
a.Package = cve.Package
a.Version = cve.Version
a.FixVersions = cve.FixVersions
a.FixedState = cve.FixedState
cveSummary[i] = a
i++
}
return cveSummary
}

func convertToReportSummary(input map[string]*imageprinter.SeveritySummary) map[string]*reportsummary.SeveritySummary {
output := make(map[string]*reportsummary.SeveritySummary)
for key, value := range input {
output[key] = &reportsummary.SeveritySummary{
NumberOfCVEs: value.NumberOfCVEs,
NumberOfFixableCVEs: value.NumberOfFixableCVEs,
}
}
return output
}

func (jp *JsonPrinter) PrintImageScan(ctx context.Context, scanResults *models.PresenterConfig) error {
if scanResults == nil {
return fmt.Errorf("no image vulnerability data provided")
Expand Down
109 changes: 109 additions & 0 deletions core/pkg/resultshandling/printer/v2/jsonprinter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"os"
"testing"

"github.com/kubescape/kubescape/v3/core/pkg/resultshandling/printer/v2/prettyprinter/tableprinter/imageprinter"
"github.com/kubescape/opa-utils/reporthandling/results/v1/reportsummary"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -83,3 +85,110 @@ func TestScore_Json(t *testing.T) {
})
}
}
func TestConvertToCVESummary(t *testing.T) {
cves := []imageprinter.CVE{
{
Severity: "High",
ID: "CVE-2021-1234",
Package: "example-package",
Version: "1.0.0",
FixVersions: []string{"1.0.1", "1.0.2"},
FixedState: "true",
},
{
Severity: "Medium",
ID: "CVE-2021-5678",
Package: "another-package",
Version: "2.0.0",
FixVersions: []string{"2.0.1"},
FixedState: "false",
},
}

want := []reportsummary.CVESummary{
{
Severity: "High",
ID: "CVE-2021-1234",
Package: "example-package",
Version: "1.0.0",
FixVersions: []string{"1.0.1", "1.0.2"},
FixedState: "true",
},
{
Severity: "Medium",
ID: "CVE-2021-5678",
Package: "another-package",
Version: "2.0.0",
FixVersions: []string{"2.0.1"},
FixedState: "false",
},
}

got := convertToCVESummary(cves)

assert.Equal(t, want, got)
}

func TestConvertToPackageScores(t *testing.T) {
packageScores := map[string]*imageprinter.PackageScore{
"example-package": {
Name: "example-package",
Version: "1.0.0",
Score: 80.0,
MapSeverityToCVEsNumber: map[string]int{"High": 2, "Medium": 1},
},
"another-package": {
Name: "another-package",
Version: "2.0.0",
Score: 60.0,
MapSeverityToCVEsNumber: map[string]int{"High": 1, "Medium": 0},
},
}

want := map[string]*reportsummary.PackageSummary{
"example-package": {
Name: "example-package",
Version: "1.0.0",
Score: 80.0,
MapSeverityToCVEsNumber: map[string]int{"High": 2, "Medium": 1},
},
"another-package": {
Name: "another-package",
Version: "2.0.0",
Score: 60.0,
MapSeverityToCVEsNumber: map[string]int{"High": 1, "Medium": 0},
},
}

got := convertToPackageScores(packageScores)

assert.Equal(t, want, got)
}

func TestConvertToReportSummary(t *testing.T) {
input := map[string]*imageprinter.SeveritySummary{
"High": &imageprinter.SeveritySummary{
NumberOfCVEs: 10,
NumberOfFixableCVEs: 5,
},
"Medium": &imageprinter.SeveritySummary{
NumberOfCVEs: 5,
NumberOfFixableCVEs: 2,
},
}

want := map[string]*reportsummary.SeveritySummary{
"High": &reportsummary.SeveritySummary{
NumberOfCVEs: 10,
NumberOfFixableCVEs: 5,
},
"Medium": &reportsummary.SeveritySummary{
NumberOfCVEs: 5,
NumberOfFixableCVEs: 2,
},
}

got := convertToReportSummary(input)

assert.Equal(t, want, got)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ require (
github.com/kubescape/go-git-url v0.0.27
github.com/kubescape/go-logger v0.0.22
github.com/kubescape/k8s-interface v0.0.161
github.com/kubescape/opa-utils v0.0.277
github.com/kubescape/opa-utils v0.0.278
github.com/kubescape/rbac-utils v0.0.21-0.20230806101615-07e36f555520
github.com/kubescape/regolibrary v1.0.315
github.com/maruel/natural v1.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1148,8 +1148,8 @@ github.com/kubescape/go-logger v0.0.22 h1:gle7wH6emOiGv9ljdpVi82pWLQ3jGucrUucvil
github.com/kubescape/go-logger v0.0.22/go.mod h1:x3HBpZo3cMT/WIdy18BxvVVd5D0e/PWFVk/HiwBNu3g=
github.com/kubescape/k8s-interface v0.0.161 h1:v6b3/kmA4o/2niNrejrbXj5X9MLfH0UrpI3s+e/fdwc=
github.com/kubescape/k8s-interface v0.0.161/go.mod h1:oF+Yxug3Kpfu9Yr2j63wy7gwswrKXpiqI0mLk/7gF/s=
github.com/kubescape/opa-utils v0.0.277 h1:nlzhvHZE0mAQ6YTtNgod4nI0wKwL9/7yCynobbKn2go=
github.com/kubescape/opa-utils v0.0.277/go.mod h1:N/UnbZHpoiHQH7O50yadhIXZvVl0IVtTGBmePPrSQSg=
github.com/kubescape/opa-utils v0.0.278 h1:x0akigrjYjocD0HzlRZ4+ZgL+ZK33286d2L48z6m0PE=
github.com/kubescape/opa-utils v0.0.278/go.mod h1:N/UnbZHpoiHQH7O50yadhIXZvVl0IVtTGBmePPrSQSg=
github.com/kubescape/rbac-utils v0.0.21-0.20230806101615-07e36f555520 h1:SqlwF8G+oFazeYmZQKoPczLEflBQpwpHCU8DoLLyfj8=
github.com/kubescape/rbac-utils v0.0.21-0.20230806101615-07e36f555520/go.mod h1:wuxMUSDzGUyWd25IJfBzEJ/Udmw2Vy7npj+MV3u3GrU=
github.com/kubescape/regolibrary v1.0.315 h1:Oyr+K8QsOnOulzVkIqOcIoK+g+NDIdoRvTG54BhCh3Q=
Expand Down
2 changes: 1 addition & 1 deletion httphandler/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/kubescape/go-logger v0.0.22
github.com/kubescape/k8s-interface v0.0.161
github.com/kubescape/kubescape/v3 v3.0.0-00010101000000-000000000000
github.com/kubescape/opa-utils v0.0.277
github.com/kubescape/opa-utils v0.0.278
github.com/kubescape/storage v0.0.20
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.8.4
Expand Down

0 comments on commit fad8f2b

Please sign in to comment.