mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
* phase-1 Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io> * factory Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io> * wip: feat(cli): add an image scanning command Add a CLI command that launches an image scan. Does not scan images yet. Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * wip: feat: add image scanning service Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * chore: include dependencies Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * wip: adjust image scanning service Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * wip: feat: use scanning service in CLI Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * use iface Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io> * touches Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io> * continue Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io> * add cmd Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io> * support single workload scan Signed-off-by: Amir Malka <amirm@armosec.io> * fix conflict Signed-off-by: Amir Malka <amirm@armosec.io> * identifiers * go mod * feat(imagescan): add an image scanning command This commit adds a CLI command and an associated package that scan images for vulnerabilities. Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> feat(imagescan): fail on exceeding the severity threshold Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * chore(imagescan): include dependencies This commit adds the dependencies necessary for image scanning. Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * chore(imagescan): add dependencies to httphandler Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * added unit tests Signed-off-by: Amir Malka <amirm@armosec.io> * merge * more * integrate img scan * added unit tests Signed-off-by: Amir Malka <amirm@armosec.io> * more refactoring Signed-off-by: Amir Malka <amirm@armosec.io> * add scanned workload reference to opasessionobj Signed-off-by: Amir Malka <amirm@armosec.io> * fix GetWorkloadParentKind Signed-off-by: Amir Malka <amirm@armosec.io> * remove namespace argument from pullSingleResource, using field selector instead Signed-off-by: Amir Malka <amirm@armosec.io> * removed designators (unused) field from PolicyIdentifier, and designators argument from GetResources function Signed-off-by: Amir Malka <amirm@armosec.io> * changes * changes * fixes * changes * feat(imagescan): add an image scanning command This commit adds a CLI command and an associated package that scan images for vulnerabilities. Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> feat(imagescan): fail on exceeding the severity threshold Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * chore(imagescan): include dependencies This commit adds the dependencies necessary for image scanning. Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * chore(imagescan): add dependencies to httphandler Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * chore(imagescan): create vuln db with dedicated function Remove commented out code, too. Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * docs(imagescan): provide package-level docs Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> * finish merge * image scan tests * continue * fixes * refactor * rm duplicate * start fixes * update gh actions Signed-off-by: David Wertenteil <dwertent@armosec.io> * pr fixes * fix test * improvements --------- Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io> Signed-off-by: Vlad Klokun <vklokun@protonmail.ch> Signed-off-by: Amir Malka <amirm@armosec.io> Signed-off-by: David Wertenteil <dwertent@armosec.io> Co-authored-by: Daniel Grunberger <danielgrunberger@armosec.io> Co-authored-by: Vlad Klokun <vklokun@protonmail.ch> Co-authored-by: Amir Malka <amirm@armosec.io> Co-authored-by: David Wertenteil <dwertent@armosec.io>
134 lines
4.2 KiB
Go
134 lines
4.2 KiB
Go
package resultshandling
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
|
||
logger "github.com/kubescape/go-logger"
|
||
"github.com/kubescape/go-logger/helpers"
|
||
"github.com/kubescape/kubescape/v2/core/cautils"
|
||
"github.com/kubescape/kubescape/v2/core/pkg/resultshandling/printer"
|
||
printerv1 "github.com/kubescape/kubescape/v2/core/pkg/resultshandling/printer/v1"
|
||
printerv2 "github.com/kubescape/kubescape/v2/core/pkg/resultshandling/printer/v2"
|
||
"github.com/kubescape/kubescape/v2/core/pkg/resultshandling/reporter"
|
||
reporthandlingv2 "github.com/kubescape/opa-utils/reporthandling/v2"
|
||
)
|
||
|
||
type ResultsHandler struct {
|
||
ReporterObj reporter.IReport
|
||
UiPrinter printer.IPrinter
|
||
ScanData *cautils.OPASessionObj
|
||
PrinterObjs []printer.IPrinter
|
||
ImageScanData []cautils.ImageScanData
|
||
}
|
||
|
||
func NewResultsHandler(reporterObj reporter.IReport, printerObjs []printer.IPrinter, uiPrinter printer.IPrinter) *ResultsHandler {
|
||
return &ResultsHandler{
|
||
ReporterObj: reporterObj,
|
||
PrinterObjs: printerObjs,
|
||
UiPrinter: uiPrinter,
|
||
ImageScanData: make([]cautils.ImageScanData, 0),
|
||
}
|
||
}
|
||
|
||
// GetRiskScore returns the result’s risk score
|
||
func (rh *ResultsHandler) GetRiskScore() float32 {
|
||
return rh.ScanData.Report.SummaryDetails.Score
|
||
}
|
||
|
||
// GetComplianceScore returns the result’s compliance score
|
||
func (rh *ResultsHandler) GetComplianceScore() float32 {
|
||
return rh.ScanData.Report.SummaryDetails.ComplianceScore
|
||
}
|
||
|
||
// GetData returns scan/action related data (policies, resources, results, etc.)
|
||
//
|
||
// Call the ToJson() method if you want the JSON representation of the data
|
||
func (rh *ResultsHandler) GetData() *cautils.OPASessionObj {
|
||
return rh.ScanData
|
||
}
|
||
|
||
// SetData sets the scan/action related data
|
||
func (rh *ResultsHandler) SetData(data *cautils.OPASessionObj) {
|
||
rh.ScanData = data
|
||
}
|
||
|
||
// GetPrinter returns all printers
|
||
func (rh *ResultsHandler) GetPrinters() []printer.IPrinter {
|
||
return rh.PrinterObjs
|
||
}
|
||
|
||
// GetReporter returns the reporter object
|
||
func (rh *ResultsHandler) GetReporter() reporter.IReport {
|
||
return rh.ReporterObj
|
||
}
|
||
|
||
// ToJson returns the results in the JSON format
|
||
func (rh *ResultsHandler) ToJson() ([]byte, error) {
|
||
return json.Marshal(printerv2.FinalizeResults(rh.ScanData))
|
||
}
|
||
|
||
// GetResults returns the results
|
||
func (rh *ResultsHandler) GetResults() *reporthandlingv2.PostureReport {
|
||
return printerv2.FinalizeResults(rh.ScanData)
|
||
}
|
||
|
||
// HandleResults handles all necessary actions for the scan results
|
||
func (rh *ResultsHandler) HandleResults(ctx context.Context) error {
|
||
// Display scan results in the UI first to give immediate value.
|
||
|
||
rh.UiPrinter.ActionPrint(ctx, rh.ScanData, rh.ImageScanData)
|
||
|
||
rh.UiPrinter.PrintNextSteps()
|
||
|
||
// Then print to output files
|
||
for _, printer := range rh.PrinterObjs {
|
||
printer.ActionPrint(ctx, rh.ScanData, rh.ImageScanData)
|
||
if rh.ScanData != nil {
|
||
printer.Score(rh.GetComplianceScore())
|
||
}
|
||
}
|
||
|
||
// We should submit only after printing results, so a user can see
|
||
// results at all times, even if submission fails
|
||
if rh.ReporterObj != nil {
|
||
if err := rh.ReporterObj.Submit(ctx, rh.ScanData); err != nil {
|
||
return err
|
||
}
|
||
rh.ReporterObj.DisplayReportURL()
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// NewPrinter returns a new printer for a given format and configuration options
|
||
func NewPrinter(ctx context.Context, printFormat, formatVersion string, verboseMode, attackTree bool, viewType cautils.ViewTypes) printer.IPrinter {
|
||
|
||
switch printFormat {
|
||
case printer.JsonFormat:
|
||
switch formatVersion {
|
||
case "v1":
|
||
logger.L().Ctx(ctx).Warning("Deprecated format version", helpers.String("run", "--format-version=v2"))
|
||
return printerv1.NewJsonPrinter()
|
||
default:
|
||
return printerv2.NewJsonPrinter()
|
||
}
|
||
case printer.JunitResultFormat:
|
||
return printerv2.NewJunitPrinter(verboseMode)
|
||
case printer.PrometheusFormat:
|
||
return printerv2.NewPrometheusPrinter(verboseMode)
|
||
case printer.PdfFormat:
|
||
return printerv2.NewPdfPrinter()
|
||
case printer.HtmlFormat:
|
||
return printerv2.NewHtmlPrinter()
|
||
case printer.SARIFFormat:
|
||
return printerv2.NewSARIFPrinter()
|
||
default:
|
||
if printFormat != printer.PrettyFormat {
|
||
logger.L().Ctx(ctx).Warning(fmt.Sprintf("Invalid format \"%s\", default format \"pretty-printer\" is applied", printFormat))
|
||
}
|
||
return printerv2.NewPrettyPrinter(verboseMode, formatVersion, attackTree, viewType, "", nil)
|
||
}
|
||
}
|