Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AST-37225 support containers in result show command #683

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion internal/commands/cx_result_sonar.json

This file was deleted.

174 changes: 132 additions & 42 deletions internal/commands/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ const (
lowCx = "LOW"
mediumCx = "MEDIUM"
highCx = "HIGH"
tableResultsFormat = " | %-10s %4d %6d %4d %4d %-9s |\n"
stringTableResultsFormat = " | %-10s %4s %6s %4s %4s %5s |\n"
TableTitleFormat = " | %-11s %4s %6s %4s %4s %6s |\n"
twoNewLines = "\n\n"
tableLine = " --------------------------------------------------------- "
codeBashingKey = "cb-url"
OrShamirCM marked this conversation as resolved.
Show resolved Hide resolved
failedGettingBfl = "Failed getting BFL"
notAvailableString = "-"
Expand Down Expand Up @@ -138,6 +143,10 @@ var sonarSeverities = map[string]string{
highCx: highSonar,
}

var containerSupportedAgents = []string{
commonParams.DefaultAgent,
}

func NewResultsCommand(
resultsWrapper wrappers.ResultsWrapper,
scanWrapper wrappers.ScansWrapper,
Expand Down Expand Up @@ -199,6 +208,7 @@ func resultShowSubCommand(
printer.FormatPDF,
printer.FormatSummaryMarkdown,
printer.FormatGL,
// printer.FormatSonar ??
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we support also this format, I don't know why it is not on the list already

)
resultShowCmd.PersistentFlags().String(commonParams.ReportFormatPdfToEmailFlag, "", pdfToEmailFlagDescription)
resultShowCmd.PersistentFlags().String(commonParams.ReportSbomFormatFlag, defaultSbomOption, sbomReportFlagDescription)
Expand Down Expand Up @@ -356,12 +366,18 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr
sastIssues := 0
scaIssues := 0
kicsIssues := 0
var containersIssues *int
enginesStatusCode := map[string]int{
commonParams.SastType: 0,
commonParams.ScaType: 0,
commonParams.KicsType: 0,
commonParams.APISecType: 0,
}
if wrappers.IsContainersEnabled {
containersIssues = new(int)
*containersIssues = 0
enginesStatusCode[commonParams.ContainersType] = 0
}

if len(scanInfo.StatusDetails) > 0 {
for _, statusDetailItem := range scanInfo.StatusDetails {
Expand All @@ -372,6 +388,8 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr
scaIssues = notAvailableNumber
} else if statusDetailItem.Name == commonParams.KicsType {
kicsIssues = notAvailableNumber
} else if statusDetailItem.Name == commonParams.ContainersType && wrappers.IsContainersEnabled {
*containersIssues = notAvailableNumber
}
}
switch statusDetailItem.Status {
Expand All @@ -383,31 +401,34 @@ func convertScanToResultsSummary(scanInfo *wrappers.ScanResponseModel, resultsWr
}
}
summary := &wrappers.ResultSummary{
ScanID: scanInfo.ID,
Status: string(scanInfo.Status),
CreatedAt: scanInfo.CreatedAt.Format("2006-01-02, 15:04:05"),
ProjectID: scanInfo.ProjectID,
RiskStyle: "",
RiskMsg: "",
HighIssues: 0,
MediumIssues: 0,
LowIssues: 0,
InfoIssues: 0,
SastIssues: sastIssues,
KicsIssues: kicsIssues,
ScaIssues: scaIssues,
Tags: scanInfo.Tags,
ProjectName: scanInfo.ProjectName,
BranchName: scanInfo.Branch,
EnginesEnabled: scanInfo.Engines,
ScanID: scanInfo.ID,
Status: string(scanInfo.Status),
CreatedAt: scanInfo.CreatedAt.Format("2006-01-02, 15:04:05"),
ProjectID: scanInfo.ProjectID,
RiskStyle: "",
RiskMsg: "",
HighIssues: 0,
MediumIssues: 0,
LowIssues: 0,
InfoIssues: 0,
SastIssues: sastIssues,
KicsIssues: kicsIssues,
ScaIssues: scaIssues,
ContainersIssues: containersIssues,
Tags: scanInfo.Tags,
ProjectName: scanInfo.ProjectName,
BranchName: scanInfo.Branch,
EnginesEnabled: scanInfo.Engines,
EnginesResult: map[string]*wrappers.EngineResultSummary{
commonParams.SastType: {StatusCode: enginesStatusCode[commonParams.SastType]},
commonParams.ScaType: {StatusCode: enginesStatusCode[commonParams.ScaType]},
commonParams.KicsType: {StatusCode: enginesStatusCode[commonParams.KicsType]},
commonParams.APISecType: {StatusCode: enginesStatusCode[commonParams.APISecType]},
},
}

if wrappers.IsContainersEnabled {
summary.EnginesResult[commonParams.ContainersType] = &wrappers.EngineResultSummary{StatusCode: enginesStatusCode[commonParams.ContainersType]}
}
baseURI, err := resultsWrapper.GetResultsURL(summary.ProjectID)
if err != nil {
return nil, err
Expand Down Expand Up @@ -451,6 +472,9 @@ func summaryReport(
setNotAvailableNumberIfZero(summary, &summary.SastIssues, commonParams.SastType)
setNotAvailableNumberIfZero(summary, &summary.ScaIssues, commonParams.ScaType)
setNotAvailableNumberIfZero(summary, &summary.KicsIssues, commonParams.KicsType)
if wrappers.IsContainersEnabled {
setNotAvailableNumberIfZero(summary, summary.ContainersIssues, commonParams.ContainersType)
}
setRiskMsgAndStyle(summary)
setNotAvailableEnginesStatusCode(summary)

Expand Down Expand Up @@ -494,6 +518,9 @@ func enhanceWithScanSummary(summary *wrappers.ResultSummary, results *wrappers.S
summary.EnginesResult[commonParams.APISecType].High = summary.APISecurity.Risks[1]
}
summary.TotalIssues = summary.SastIssues + summary.ScaIssues + summary.KicsIssues + summary.GetAPISecurityDocumentationTotal()
if wrappers.IsContainersEnabled {
summary.TotalIssues += *summary.ContainersIssues
}
}

func writeHTMLSummary(targetFile string, summary *wrappers.ResultSummary) error {
Expand Down Expand Up @@ -559,7 +586,7 @@ func writeConsoleSummary(summary *wrappers.ResultSummary) error {
}

func printPoliciesSummary(summary *wrappers.ResultSummary) {
fmt.Printf(" -------------------------------------- \n")
fmt.Printf(tableLine + "\n")
if summary.Policies.BreakBuild {
fmt.Printf(" Policy Management Violation - Break Build Enabled: \n")
} else {
Expand All @@ -585,22 +612,19 @@ func printAPIsSecuritySummary(summary *wrappers.ResultSummary) {
if summary.HasAPISecurityDocumentation() {
fmt.Printf(" APIS DOCUMENTATION: %*d \n", defaultPaddingSize, summary.GetAPISecurityDocumentationTotal())
}
fmt.Printf(" -------------------------------------------------- \n\n")
fmt.Printf(tableLine + twoNewLines)
}

func printTableRow(title string, counts *wrappers.EngineResultSummary, statusNumber int) {
formatString := " | %-4s %4d %6d %4d %4d %-9s |\n"
notAvailableFormatString := " | %-4s %4s %6s %4s %4s %5s |\n"

switch statusNumber {
case notAvailableNumber:
fmt.Printf(notAvailableFormatString, title, notAvailableString, notAvailableString, notAvailableString, notAvailableString, notAvailableString)
fmt.Printf(stringTableResultsFormat, title, notAvailableString, notAvailableString, notAvailableString, notAvailableString, notAvailableString)
case scanFailedNumber:
fmt.Printf(formatString, title, counts.High, counts.Medium, counts.Low, counts.Info, scanFailedString)
fmt.Printf(tableResultsFormat, title, counts.High, counts.Medium, counts.Low, counts.Info, scanFailedString)
case scanCanceledNumber:
fmt.Printf(formatString, title, counts.High, counts.Medium, counts.Low, counts.Info, scanCanceledString)
fmt.Printf(tableResultsFormat, title, counts.High, counts.Medium, counts.Low, counts.Info, scanCanceledString)
default:
fmt.Printf(formatString, title, counts.High, counts.Medium, counts.Low, counts.Info, scanSuccessString)
fmt.Printf(tableResultsFormat, title, counts.High, counts.Medium, counts.Low, counts.Info, scanSuccessString)
}
}

Expand All @@ -609,20 +633,23 @@ func printResultsSummaryTable(summary *wrappers.ResultSummary) {
totalMediumIssues := summary.EnginesResult.GetMediumIssues()
totalLowIssues := summary.EnginesResult.GetLowIssues()
totalInfoIssues := summary.EnginesResult.GetInfoIssues()
fmt.Printf(" --------------------------------------------------- \n\n")
fmt.Printf(tableLine + twoNewLines)
fmt.Printf(" Total Results: %d \n", summary.TotalIssues)
fmt.Println(" --------------------------------------------------- ")
fmt.Println(" | High Medium Low Info Status |")
fmt.Println(tableLine)
fmt.Printf(TableTitleFormat, " ", "High", "Medium", "Low", "Info", "Status")

printTableRow("APIs", summary.EnginesResult[commonParams.APISecType], summary.EnginesResult[commonParams.APISecType].StatusCode)
printTableRow("IAC", summary.EnginesResult[commonParams.KicsType], summary.EnginesResult[commonParams.KicsType].StatusCode)
printTableRow("SAST", summary.EnginesResult[commonParams.SastType], summary.EnginesResult[commonParams.SastType].StatusCode)
printTableRow("SCA", summary.EnginesResult[commonParams.ScaType], summary.EnginesResult[commonParams.ScaType].StatusCode)
if wrappers.IsContainersEnabled {
printTableRow("CONTAINERS", summary.EnginesResult[commonParams.ContainersType], summary.EnginesResult[commonParams.ContainersType].StatusCode)
}

fmt.Println(" --------------------------------------------------- ")
fmt.Printf(" | %-4s %4d %6d %4d %4d %-9s |\n",
fmt.Sprintf(boldFormat, "TOTAL"), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status)
fmt.Printf(" --------------------------------------------------- \n\n")
fmt.Println(tableLine)
fmt.Printf(tableResultsFormat,
fmt.Sprintf(boldFormat, "TOTAL "), totalHighIssues, totalMediumIssues, totalLowIssues, totalInfoIssues, summary.Status)
fmt.Printf(tableLine + twoNewLines)
}

func generateScanSummaryURL(summary *wrappers.ResultSummary) string {
Expand Down Expand Up @@ -651,6 +678,7 @@ func runGetResultCommand(
useSCALocalFlow, _ := cmd.Flags().GetBool(commonParams.ReportSbomFormatLocalFlowFlag)
retrySBOM, _ := cmd.Flags().GetInt(commonParams.RetrySBOMFlag)
sastRedundancy, _ := cmd.Flags().GetBool(commonParams.SastRedundancyFlag)
agent, _ := cmd.Flags().GetString(commonParams.AgentFlag)

scanID, _ := cmd.Flags().GetString(commonParams.ScanIDFlag)
if scanID == "" {
Expand Down Expand Up @@ -683,7 +711,6 @@ func runGetResultCommand(
} else {
logger.PrintIfVerbose("Skipping policy evaluation")
}

if sastRedundancy {
params[commonParams.SastRedundancyFlag] = ""
}
Expand All @@ -703,6 +730,7 @@ func runGetResultCommand(
formatSbomOptions,
targetFile,
targetPath,
agent,
params)
}
}
Expand Down Expand Up @@ -746,7 +774,10 @@ func runGetCodeBashingCommand(
return nil
}
}

func setIsContainersEnabled(agent string) {
agentSupported := contains(containerSupportedAgents, agent)
wrappers.IsContainersEnabled = wrappers.FeatureFlags[wrappers.ContainerEngineCLIEnabled] && agentSupported
}
func CreateScanReport(
resultsWrapper wrappers.ResultsWrapper,
risksOverviewWrapper wrappers.RisksOverviewWrapper,
Expand All @@ -762,11 +793,12 @@ func CreateScanReport(
formatSbomOptions,
targetFile,
targetPath string,
agent string,
params map[string]string,
) error {
reportList := strings.Split(reportTypes, ",")
results := &wrappers.ScanResultsCollection{}

setIsContainersEnabled(agent)
summary, err := convertScanToResultsSummary(scan, resultsWrapper)
if err != nil {
return err
Expand Down Expand Up @@ -814,14 +846,22 @@ func countResult(summary *wrappers.ResultSummary, result *wrappers.ScanResult) {
} else if engineType == commonParams.KicsType {
summary.KicsIssues++
summary.TotalIssues++
} else if engineType == commonParams.ContainersType {
if wrappers.IsContainersEnabled {
*summary.ContainersIssues++
summary.TotalIssues++
} else {
return
OrShamirCM marked this conversation as resolved.
Show resolved Hide resolved
}
}
if severity == highLabel {
switch severity {
case highLabel:
summary.HighIssues++
} else if severity == lowLabel {
summary.LowIssues++
} else if severity == mediumLabel {
case mediumLabel:
summary.MediumIssues++
} else if severity == infoLabel {
case lowLabel:
summary.LowIssues++
case infoLabel:
summary.InfoIssues++
}
summary.UpdateEngineResultSummary(engineType, severity)
Expand Down Expand Up @@ -1039,9 +1079,24 @@ func enrichScaResults(
// Compute SAST results redundancy
resultsModel = ComputeRedundantSastResults(resultsModel)
}
if util.Contains(scan.Engines, commonParams.ContainersType) && !wrappers.IsContainersEnabled {
resultsModel = removeContainerResults(resultsModel)
}
return resultsModel, nil
}

func removeContainerResults(model *wrappers.ScanResultsCollection) *wrappers.ScanResultsCollection {
var newResults []*wrappers.ScanResult
for _, result := range model.Results {
if result.Type != commonParams.ContainersType {
newResults = append(newResults, result)
}
}
model.Results = newResults
model.TotalCount = uint(len(newResults))
OrShamirCM marked this conversation as resolved.
Show resolved Hide resolved
return model
}

func exportSarifResults(targetFile string, results *wrappers.ScanResultsCollection) error {
var err error
var resultsJSON []byte
Expand Down Expand Up @@ -1446,12 +1501,28 @@ func parseResultsSonar(results *wrappers.ScanResultsCollection) []wrappers.Sonar
} else if engineType == commonParams.ScaType {
sonarIssuesByLocation := parseScaSonarLocations(result)
sonarIssues = append(sonarIssues, sonarIssuesByLocation...)
} else if wrappers.IsContainersEnabled && engineType == commonParams.ContainersType {
auxIssue.PrimaryLocation = parseContainersSonar(result)
sonarIssues = append(sonarIssues, auxIssue)
}
}
}
return sonarIssues
}

func parseContainersSonar(result *wrappers.ScanResult) wrappers.SonarLocation {
var auxLocation wrappers.SonarLocation
auxLocation.FilePath = result.ScanResultData.ImageFilePath
auxLocation.Message = result.Description
var textRange wrappers.SonarTextRange
textRange.StartColumn = 1
textRange.EndColumn = 2
textRange.StartLine = 1
textRange.EndLine = 2
auxLocation.TextRange = textRange
return auxLocation
}

func initSonarIssue(result *wrappers.ScanResult) wrappers.SonarIssues {
var sonarIssue wrappers.SonarIssues
sonarIssue.Severity = sonarSeverities[result.Severity]
Expand Down Expand Up @@ -1645,6 +1716,8 @@ func findResult(result *wrappers.ScanResult) []wrappers.SarifScanResult {
scanResults = parseSarifResultKics(result, scanResults)
} else if result.Type == commonParams.ScaType {
scanResults = parseSarifResultsSca(result, scanResults)
} else if result.Type == commonParams.ContainersType && wrappers.IsContainersEnabled {
scanResults = parseSarifResultsContainers(result, scanResults)
}

if len(scanResults) > 0 {
Expand All @@ -1653,6 +1726,21 @@ func findResult(result *wrappers.ScanResult) []wrappers.SarifScanResult {
return nil
}

func parseSarifResultsContainers(result *wrappers.ScanResult, scanResults []wrappers.SarifScanResult) []wrappers.SarifScanResult {
var scanResult = initSarifResult(result)
var scanLocation wrappers.SarifLocation

scanLocation.PhysicalLocation.ArtifactLocation.URI = result.ScanResultData.ImageFilePath
scanLocation.PhysicalLocation.Region = &wrappers.SarifRegion{}
scanLocation.PhysicalLocation.Region.StartLine = 1
scanLocation.PhysicalLocation.Region.StartColumn = 1
scanLocation.PhysicalLocation.Region.EndColumn = 2
scanResult.Locations = append(scanResult.Locations, scanLocation)

scanResults = append(scanResults, scanResult)
return scanResults
}

func parseSarifResultsSca(result *wrappers.ScanResult, scanResults []wrappers.SarifScanResult) []wrappers.SarifScanResult {
if result == nil || result.ScanResultData.ScaPackageCollection == nil || result.ScanResultData.ScaPackageCollection.Locations == nil {
return scanResults
Expand Down Expand Up @@ -1728,6 +1816,8 @@ func convertNotAvailableNumberToZero(summary *wrappers.ResultSummary) {
summary.SastIssues = 0
} else if summary.ScaIssues == notAvailableNumber {
summary.ScaIssues = 0
} else if wrappers.IsContainersEnabled && *summary.ContainersIssues == notAvailableNumber {
*summary.ContainersIssues = 0
}
}

Expand Down
Loading
Loading