Skip to content

Commit

Permalink
Improve Job Summary (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
attiasas authored Aug 30, 2024
1 parent ecefbeb commit e5f675e
Show file tree
Hide file tree
Showing 37 changed files with 1,936 additions and 1,077 deletions.
2 changes: 1 addition & 1 deletion cli/scancommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ func ShouldRunCurationAfterFailure(c *components.Context, tech techutils.Technol
if !IsSupportedCommandForCurationInspect(cmdName) {
return
}
if os.Getenv(coreutils.OutputDirPathEnv) == "" ||
if os.Getenv(coreutils.SummaryOutputDirPathEnv) == "" ||
os.Getenv(SkipCurationAfterFailureEnv) == "true" {
return
}
Expand Down
2 changes: 1 addition & 1 deletion cli/scancommands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func TestShouldRunCurationAfterFailure(t *testing.T) {
defer callBack()
}
if tt.envOutputDirPath != "" {
callBack2 := clienttestutils.SetEnvWithCallbackAndAssert(t, coreutils.OutputDirPathEnv, tt.envOutputDirPath)
callBack2 := clienttestutils.SetEnvWithCallbackAndAssert(t, coreutils.SummaryOutputDirPathEnv, tt.envOutputDirPath)
defer callBack2()
}

Expand Down
50 changes: 28 additions & 22 deletions commands/curation/curationaudit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"errors"
"fmt"
"golang.org/x/exp/maps"

"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/gofrog/parallel"
rtUtils "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
Expand Down Expand Up @@ -240,50 +242,54 @@ func (ca *CurationAuditCommand) Run() (err error) {
for projectPath, packagesStatus := range results {
err = errors.Join(err, printResult(ca.OutputFormat(), projectPath, packagesStatus.packagesStatus))
}

err = errors.Join(err, utils.RecordSecurityCommandOutput(utils.ScanCommandSummaryResult{Results: convertResultsToSummary(results), Section: utils.Curation}))
err = errors.Join(err, utils.RecordSecurityCommandSummary(utils.NewCurationSummary(convertResultsToSummary(results))))
return
}

func convertResultsToSummary(results map[string]*CurationReport) formats.SummaryResults {
summaryResults := formats.SummaryResults{}
func convertResultsToSummary(results map[string]*CurationReport) formats.ResultsSummary {
summaryResults := formats.ResultsSummary{}
for projectPath, packagesStatus := range results {
blocked := convertBlocked(packagesStatus.packagesStatus)
approved := packagesStatus.totalNumberOfPackages - blocked.GetCountOfKeys(false)

summaryResults.Scans = append(summaryResults.Scans, formats.ScanSummaryResult{Target: projectPath,
summaryResults.Scans = append(summaryResults.Scans, formats.ScanSummary{Target: projectPath,
CuratedPackages: &formats.CuratedPackages{
Blocked: blocked,
Approved: approved,
}})
PackageCount: packagesStatus.totalNumberOfPackages,
Blocked: getBlocked(packagesStatus.packagesStatus),
},
})
}
return summaryResults
}

func convertBlocked(pkgStatus []*PackageStatus) formats.TwoLevelSummaryCount {
blocked := formats.TwoLevelSummaryCount{}
func getBlocked(pkgStatus []*PackageStatus) []formats.BlockedPackages {
blockedMap := map[string]formats.BlockedPackages{}
for _, pkg := range pkgStatus {
for _, policy := range pkg.Policy {
polAndCond := formatPolicyAndCond(policy.Policy, policy.Condition)
if _, ok := blocked[polAndCond]; !ok {
blocked[polAndCond] = formats.SummaryCount{}
polAndCondKey := getPolicyAndConditionId(policy.Policy, policy.Condition)
if _, ok := blockedMap[polAndCondKey]; !ok {
blockedMap[polAndCondKey] = formats.BlockedPackages{
Policy: policy.Policy,
Condition: policy.Condition,
Packages: make(map[string]int),
}
}
uniqId := getPackageId(pkg.PackageName, pkg.PackageVersion)
blocked[polAndCond][uniqId]++
if _, ok := blockedMap[polAndCondKey].Packages[uniqId]; !ok {
blockedMap[polAndCondKey].Packages[uniqId] = 0
}
blockedMap[polAndCondKey].Packages[uniqId]++
}
}
return blocked
}

func formatPolicyAndCond(policy, cond string) string {
return fmt.Sprintf("Policy: %s, Condition: %s", policy, cond)
return maps.Values(blockedMap)
}

// The unique identifier of a package includes the package name with its version
func getPackageId(packageName, packageVersion string) string {
return fmt.Sprintf("%s:%s", packageName, packageVersion)
}

func getPolicyAndConditionId(policy, condition string) string {
return fmt.Sprintf("%s:%s", policy, condition)
}

func (ca *CurationAuditCommand) doCurateAudit(results map[string]*CurationReport) error {
techs := techutils.DetectedTechnologiesList()
for _, tech := range techs {
Expand Down
45 changes: 23 additions & 22 deletions commands/curation/curationaudit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ func Test_convertResultsToSummary(t *testing.T) {
tests := []struct {
name string
input map[string]*CurationReport
expected formats.SummaryResults
expected formats.ResultsSummary
}{
{
name: "results for one result",
Expand All @@ -882,17 +882,17 @@ func Test_convertResultsToSummary(t *testing.T) {
totalNumberOfPackages: 5,
},
},
expected: formats.SummaryResults{
Scans: []formats.ScanSummaryResult{
expected: formats.ResultsSummary{
Scans: []formats.ScanSummary{
{
Target: "project1",
CuratedPackages: &formats.CuratedPackages{
Blocked: formats.TwoLevelSummaryCount{
formatPolicyAndCond("policy1", "cond1"): formats.SummaryCount{
getPackageId("test1", "1.0.0"): 1,
},
},
Approved: 4,
PackageCount: 5,
Blocked: []formats.BlockedPackages{{
Policy: "policy1",
Condition: "cond1",
Packages: map[string]int{"test1:1.0.0": 1},
}},
},
},
},
Expand Down Expand Up @@ -950,25 +950,27 @@ func Test_convertResultsToSummary(t *testing.T) {
},
},
},
totalNumberOfPackages: 5,
totalNumberOfPackages: 6,
},
},
expected: formats.SummaryResults{
Scans: []formats.ScanSummaryResult{
expected: formats.ResultsSummary{
Scans: []formats.ScanSummary{
{
Target: "project1",
CuratedPackages: &formats.CuratedPackages{
Blocked: formats.TwoLevelSummaryCount{
formatPolicyAndCond("policy1", "cond1"): formats.SummaryCount{
getPackageId("test1", "1.0.0"): 1,
PackageCount: 6,
Blocked: []formats.BlockedPackages{
{
Policy: "policy1",
Condition: "cond1",
Packages: map[string]int{"test1:1.0.0": 1},
},
formatPolicyAndCond("policy2", "cond2"): formats.SummaryCount{
getPackageId("test1", "1.0.0"): 1,
getPackageId("test2", "2.0.0"): 1,
getPackageId("test3", "3.0.0"): 1,
{
Policy: "policy2",
Condition: "cond2",
Packages: map[string]int{"test1:1.0.0": 1, "test2:2.0.0": 1, "test3:3.0.0": 1},
},
},
Approved: 2,
},
},
},
Expand All @@ -977,8 +979,7 @@ func Test_convertResultsToSummary(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
results := convertResultsToSummary(tt.input)
assert.Equal(t, tt.expected, results)
assert.ElementsMatch(t, tt.expected.Scans, convertResultsToSummary(tt.input).Scans)
})
}
}
8 changes: 7 additions & 1 deletion commands/scan/buildscan.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,13 @@ func (bsc *BuildScanCommand) runBuildScanAndPrintResults(xrayManager *xray.XrayS
}
}
}
err = utils.RecordSecurityCommandOutput(utils.ScanCommandSummaryResult{Results: scanResults.GetSummary(), Section: utils.Build})
err = utils.RecordSecurityCommandSummary(utils.NewBuildScanSummary(
scanResults,
bsc.serverDetails,
bsc.includeVulnerabilities,
bsc.buildConfiguration.GetProject() != "",
params.BuildName, params.BuildNumber,
))
return
}

Expand Down
15 changes: 9 additions & 6 deletions commands/scan/dockerscan.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,18 @@ func (dsc *DockerScanCommand) Run() (err error) {
}
}()
return dsc.ScanCommand.RunAndRecordResults(func(scanResults *utils.Results) (err error) {
if scanResults == nil || len(scanResults.ScaResults) == 0 {
if scanResults == nil {
return
}
for i := range scanResults.ScaResults {
// Set the image tag as the target for the scan results (will show `image.tar` as target if not set)
scanResults.ScaResults[i].Target = dsc.imageTag
}
dsc.analyticsMetricsService.UpdateGeneralEvent(dsc.analyticsMetricsService.CreateXscAnalyticsGeneralEventFinalizeFromAuditResults(scanResults))
return utils.RecordSecurityCommandOutput(utils.ScanCommandSummaryResult{Results: scanResults.GetSummary(), Section: utils.Binary})

return utils.RecordSecurityCommandSummary(utils.NewDockerScanSummary(
scanResults,
dsc.ScanCommand.serverDetails,
dsc.ScanCommand.includeVulnerabilities,
hasViolationContext(dsc.ScanCommand.watches, dsc.ScanCommand.projectKey),
dsc.imageTag,
))
})
}

Expand Down
13 changes: 11 additions & 2 deletions commands/scan/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,19 @@ func (scanCmd *ScanCommand) indexFile(filePath string) (*xrayUtils.BinaryGraphNo

func (scanCmd *ScanCommand) Run() (err error) {
return scanCmd.RunAndRecordResults(func(scanResults *utils.Results) error {
return utils.RecordSecurityCommandOutput(utils.ScanCommandSummaryResult{Results: scanResults.GetSummary(), Section: utils.Binary})
return utils.RecordSecurityCommandSummary(utils.NewBinaryScanSummary(
scanResults,
scanCmd.serverDetails,
scanCmd.includeVulnerabilities,
hasViolationContext(scanCmd.watches, scanCmd.projectKey),
))
})
}

func hasViolationContext(watches []string, projectKey string) bool {
return len(watches) > 0 || projectKey != ""
}

func (scanCmd *ScanCommand) RunAndRecordResults(recordResFunc func(scanResults *utils.Results) error) (err error) {
defer func() {
if err != nil {
Expand Down Expand Up @@ -312,7 +321,7 @@ func (scanCmd *ScanCommand) RunAndRecordResults(recordResFunc func(scanResults *
SetIncludeVulnerabilities(scanCmd.includeVulnerabilities).
SetIncludeLicenses(scanCmd.includeLicenses).
SetPrintExtendedTable(scanCmd.printExtendedTable).
SetIsMultipleRootProject(true).
SetIsMultipleRootProject(scanResults.IsMultipleProject()).
SetScanType(services.Binary).
PrintScanResults(); err != nil {
return
Expand Down
Loading

0 comments on commit e5f675e

Please sign in to comment.