Merge remote-tracking branch 'other/scan-workload' into new-output

This commit is contained in:
Daniel Grunberger
2023-07-30 10:08:42 +03:00
16 changed files with 182 additions and 88 deletions
+1 -2
View File
@@ -56,8 +56,7 @@ type OPASessionObj struct {
Exceptions []armotypes.PostureExceptionPolicy // list of exceptions to apply on scan results
OmitRawResources bool // omit raw resources from output
ScanType ScanTypes // scan type
ResourceIDToImageMap map[string][]string
ScannedWorkload workloadinterface.IWorkload // single workload scan
ScannedWorkload workloadinterface.IWorkload // single workload scan
}
func NewOPASessionObj(ctx context.Context, frameworks []reporthandling.Framework, k8sResources K8SResources, scanInfo *ScanInfo) *OPASessionObj {
+2 -4
View File
@@ -8,7 +8,6 @@ import (
"path/filepath"
"strings"
"github.com/armosec/armoapi-go/identifiers"
giturl "github.com/kubescape/go-git-url"
"github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
@@ -94,9 +93,8 @@ const (
)
type PolicyIdentifier struct {
Identifier string // policy Identifier e.g. c-0012 for control, nsa,mitre for frameworks
Kind apisv1.NotificationPolicyKind // policy kind e.g. Framework,Control,Rule
Designators identifiers.PortalDesignator
Identifier string // policy Identifier e.g. c-0012 for control, nsa,mitre for frameworks
Kind apisv1.NotificationPolicyKind // policy kind e.g. Framework,Control,Rule
}
type WorkloadIdentifier struct {
+4 -3
View File
@@ -65,13 +65,13 @@ func getRBACHandler(tenantConfig cautils.ITenantConfig, k8s *k8sinterface.Kubern
return nil
}
func getReporter(ctx context.Context, tenantConfig cautils.ITenantConfig, reportID string, submit, fwScan bool, scanningContext cautils.ScanningContext) reporter.IReport {
func getReporter(ctx context.Context, tenantConfig cautils.ITenantConfig, reportID string, submit, fwScan bool, scanInfo cautils.ScanInfo) reporter.IReport {
_, span := otel.Tracer("").Start(ctx, "getReporter")
defer span.End()
if submit {
submitData := reporterv2.SubmitContextScan
if scanningContext != cautils.ContextCluster {
if scanInfo.GetScanningContext() != cautils.ContextCluster {
submitData = reporterv2.SubmitContextRepository
}
return reporterv2.NewReportEventReceiver(tenantConfig.GetConfigObj(), reportID, submitData)
@@ -81,7 +81,8 @@ func getReporter(ctx context.Context, tenantConfig cautils.ITenantConfig, report
return reporterv2.NewReportMock("", "")
}
var message string
if !fwScan {
if !fwScan && scanInfo.ScanType != cautils.ScanTypeWorkload {
message = "Kubescape does not submit scan results when scanning controls"
}
+20 -8
View File
@@ -7,6 +7,7 @@ import (
"github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
"github.com/kubescape/k8s-interface/k8sinterface"
"github.com/kubescape/k8s-interface/workloadinterface"
"github.com/kubescape/kubescape/v2/core/cautils"
"github.com/kubescape/kubescape/v2/core/cautils/getter"
"github.com/kubescape/kubescape/v2/core/pkg/hostsensorutils"
@@ -94,7 +95,7 @@ func getInterfaces(ctx context.Context, scanInfo *cautils.ScanInfo) componentInt
// ================== setup reporter & printer objects ======================================
// reporting behavior - setup reporter
reportHandler := getReporter(ctx, tenantConfig, scanInfo.ScanID, scanInfo.Submit, scanInfo.FrameworkScan, scanInfo.GetScanningContext())
reportHandler := getReporter(ctx, tenantConfig, scanInfo.ScanID, scanInfo.Submit, scanInfo.FrameworkScan, *scanInfo)
// setup printers
outputPrinters := GetOutputPrinters(scanInfo, ctx)
@@ -193,7 +194,6 @@ func (ks *Kubescape) Scan(ctx context.Context, scanInfo *cautils.ScanInfo) (*res
}
// ======================== prioritization ===================
scanInfo.ScanType = cautils.ScanTypeRepo
if scanInfo.PrintAttackTree || isPrioritizationScanType(scanInfo.ScanType) {
_, spanPrioritization := otel.Tracer("").Start(ctxOpa, "prioritization")
if priotizationHandler, err := resourcesprioritization.NewResourcesPrioritizationHandler(ctxOpa, scanInfo.Getters.AttackTracksGetter, scanInfo.PrintAttackTree); err != nil {
@@ -207,7 +207,7 @@ func (ks *Kubescape) Scan(ctx context.Context, scanInfo *cautils.ScanInfo) (*res
spanPrioritization.End()
}
if scanInfo.ScanImages && len(scanData.ResourceIDToImageMap) > 0 {
if scanInfo.ScanImages {
scanImages(scanInfo, scanData, ctx, resultsHandling)
}
// ========================= results handling =====================
@@ -221,17 +221,29 @@ func (ks *Kubescape) Scan(ctx context.Context, scanInfo *cautils.ScanInfo) (*res
}
func scanImages(scanInfo *cautils.ScanInfo, scanData *cautils.OPASessionObj, ctx context.Context, resultsHandling *resultshandling.ResultsHandler) {
logger.L().Ctx(ctx).Info("Scanning images")
logger.L().Info("Scanning images")
dbCfg, _ := imagescan.NewDefaultDBConfig()
svc := imagescan.NewScanService(dbCfg)
for _, imgs := range scanData.ResourceIDToImageMap {
for _, img := range imgs {
scanSingleImage(ctx, img, svc, resultsHandling, *scanInfo)
if scanInfo.ScanType == cautils.ScanTypeWorkload {
wlObj := workloadinterface.NewWorkloadObj(scanData.ScannedWorkload.GetObject())
scanSingleWorkload(wlObj, ctx, svc, resultsHandling, scanInfo)
} else {
for _, workload := range scanData.AllResources {
wlObj := workloadinterface.NewWorkloadObj(workload.GetObject())
scanSingleWorkload(wlObj, ctx, svc, resultsHandling, scanInfo)
}
}
logger.L().Ctx(ctx).Success("Finished scanning images")
logger.L().Success("Finished scanning images")
}
func scanSingleWorkload(wlObj *workloadinterface.Workload, ctx context.Context, svc imagescan.Service, resultsHandling *resultshandling.ResultsHandler, scanInfo *cautils.ScanInfo) {
containers, _ := wlObj.GetContainers()
for _, container := range containers {
scanSingleImage(ctx, container.Image, svc, resultsHandling, *scanInfo)
}
}
func scanSingleImage(ctx context.Context, img string, svc imagescan.Service, resultsHandling *resultshandling.ResultsHandler, scanInfo cautils.ScanInfo) {
+7 -3
View File
@@ -77,20 +77,24 @@ func getNamespacesSelector(kind, ns, operator string) string {
}
if kind == "namespaces" || kind == "Namespace" {
return getNameFieldSelector(ns, operator)
return getNameFieldSelectorString(ns, operator)
}
if k8sinterface.IsResourceInNamespaceScope(kind) {
return fmt.Sprintf("metadata.namespace%s%s", operator, ns)
return getNamespaceFieldSelectorString(ns, operator)
}
return ""
}
func getNameFieldSelector(resourceName, operator string) string {
func getNameFieldSelectorString(resourceName, operator string) string {
return fmt.Sprintf("metadata.name%s%s", operator, resourceName)
}
func getNamespaceFieldSelectorString(namespace, operator string) string {
return fmt.Sprintf("metadata.namespace%s%s", operator, namespace)
}
func combineFieldSelectors(selectors ...string) string {
var nonEmptyStrings []string
for i := range selectors {
+111 -22
View File
@@ -32,13 +32,12 @@ func NewFileResourceHandler(_ context.Context, inputPatterns []string, workloadI
}
}
func (fileHandler *FileResourceHandler) GetResources(ctx context.Context, sessionObj *cautils.OPASessionObj, _ *identifiers.PortalDesignator, progressListener opaprocessor.IJobProgressNotificationClient, scanInfo cautils.ScanInfo) (cautils.K8SResources, map[string]workloadinterface.IMetadata, cautils.KSResources, map[string]bool, map[string][]string, error) {
func (fileHandler *FileResourceHandler) GetResources(ctx context.Context, sessionObj *cautils.OPASessionObj, _ *identifiers.PortalDesignator, progressListener opaprocessor.IJobProgressNotificationClient, scanInfo cautils.ScanInfo) (cautils.K8SResources, map[string]workloadinterface.IMetadata, cautils.KSResources, map[string]bool, error) {
allResources := map[string]workloadinterface.IMetadata{}
ksResources := cautils.KSResources{}
resourceIDToImages := map[string][]string{}
if len(fileHandler.inputPatterns) == 0 {
return nil, nil, nil, nil, nil, fmt.Errorf("missing input")
return nil, nil, nil, nil, fmt.Errorf("missing input")
}
logger.L().Info("Accessing local objects")
@@ -56,29 +55,13 @@ func (fileHandler *FileResourceHandler) GetResources(ctx context.Context, sessio
} else {
workloadIDToSource, workloads, err = getResourcesFromPath(ctx, fileHandler.inputPatterns[path])
if err != nil {
return nil, allResources, nil, nil, nil, err
return nil, allResources, nil, nil, err
}
}
if len(workloads) == 0 {
logger.L().Debug("path ignored because contains only a non-kubernetes file", helpers.String("path", fileHandler.inputPatterns[path]))
}
if scanInfo.ScanImages {
for i := range workloads {
wlObj := workloadinterface.NewWorkloadObj(workloads[i].GetObject())
containers, err := wlObj.GetContainers()
if err != nil {
}
for _, container := range containers {
if _, ok := resourceIDToImages[workloads[i].GetID()]; !ok {
resourceIDToImages[workloads[i].GetID()] = []string{}
}
resourceIDToImages[workloads[i].GetID()] = append(resourceIDToImages[workloads[i].GetID()], container.Image)
}
}
}
for k, v := range workloadIDToSource {
sessionObj.ResourceSource[k] = v
}
@@ -90,7 +73,7 @@ func (fileHandler *FileResourceHandler) GetResources(ctx context.Context, sessio
// locate input workload in the mapped resources - if not found or not a valid workload, return error
inputWorkload, err := findWorkloadToScan(mappedResources, fileHandler.workloadIdentifier)
if err != nil {
return nil, nil, nil, nil, nil, err
return nil, nil, nil, nil, err
}
sessionObj.ScannedWorkload = inputWorkload
@@ -117,7 +100,113 @@ func (fileHandler *FileResourceHandler) GetResources(ctx context.Context, sessio
cautils.StopSpinner()
logger.L().Success("Done accessing local objects")
return k8sResources, allResources, ksResources, excludedRulesMap, resourceIDToImages, nil
return k8sResources, allResources, ksResources, excludedRulesMap, nil
}
func getWorkloadFromHelmChart(ctx context.Context, helmPath, workloadPath string) (map[string]reporthandling.Source, []workloadinterface.IMetadata, error) {
clonedRepo, err := cloneGitRepo(&helmPath)
if err != nil {
return nil, nil, err
}
if clonedRepo != "" {
defer os.RemoveAll(clonedRepo)
}
helmSourceToWorkloads, helmSourceToChartName := cautils.LoadResourcesFromHelmCharts(ctx, helmPath)
wlSource, _ := helmSourceToWorkloads[workloadPath]
// Get repo root
repoRoot, gitRepo := extractGitRepo(helmPath)
helmChartName := helmSourceToChartName[workloadPath]
relSource, err := filepath.Rel(repoRoot, helmPath)
if err == nil {
helmPath = relSource
}
var lastCommit reporthandling.LastCommit
if gitRepo != nil {
commitInfo, _ := gitRepo.GetFileLastCommit(helmPath)
if commitInfo != nil {
lastCommit = reporthandling.LastCommit{
Hash: commitInfo.SHA,
Date: commitInfo.Author.Date,
CommitterName: commitInfo.Author.Name,
CommitterEmail: commitInfo.Author.Email,
Message: commitInfo.Message,
}
}
}
workloadSource := reporthandling.Source{
RelativePath: helmPath,
FileType: reporthandling.SourceTypeHelmChart,
HelmChartName: helmChartName,
LastCommit: lastCommit,
}
workloadIDToSource := make(map[string]reporthandling.Source, 0)
workloadIDToSource[wlSource[0].GetID()] = workloadSource
workloads := []workloadinterface.IMetadata{}
workloads = append(workloads, wlSource...)
return workloadIDToSource, workloads, nil
}
func getWorkloadFromHelmChart(ctx context.Context, helmPath, workloadPath string) (map[string]reporthandling.Source, []workloadinterface.IMetadata, error) {
clonedRepo, err := cloneGitRepo(&helmPath)
if err != nil {
return nil, nil, err
}
if clonedRepo != "" {
defer os.RemoveAll(clonedRepo)
}
helmSourceToWorkloads, helmSourceToChartName := cautils.LoadResourcesFromHelmCharts(ctx, helmPath)
wlSource, _ := helmSourceToWorkloads[workloadPath]
// Get repo root
repoRoot, gitRepo := extractGitRepo(helmPath)
helmChartName := helmSourceToChartName[workloadPath]
relSource, err := filepath.Rel(repoRoot, helmPath)
if err == nil {
helmPath = relSource
}
var lastCommit reporthandling.LastCommit
if gitRepo != nil {
commitInfo, _ := gitRepo.GetFileLastCommit(helmPath)
if commitInfo != nil {
lastCommit = reporthandling.LastCommit{
Hash: commitInfo.SHA,
Date: commitInfo.Author.Date,
CommitterName: commitInfo.Author.Name,
CommitterEmail: commitInfo.Author.Email,
Message: commitInfo.Message,
}
}
}
workloadSource := reporthandling.Source{
RelativePath: helmPath,
FileType: reporthandling.SourceTypeHelmChart,
HelmChartName: helmChartName,
LastCommit: lastCommit,
}
workloadIDToSource := make(map[string]reporthandling.Source, 0)
workloadIDToSource[wlSource[0].GetID()] = workloadSource
workloads := []workloadinterface.IMetadata{}
workloads = append(workloads, wlSource...)
return workloadIDToSource, workloads, nil
}
func getResourcesFromPath(ctx context.Context, path string) (map[string]reporthandling.Source, []workloadinterface.IMetadata, error) {
@@ -29,7 +29,7 @@ func CollectResources(ctx context.Context, rsrcHandler IResourceHandler, policyI
setCloudMetadata(opaSessionObj)
}
resourcesMap, allResources, ksResources, excludedRulesMap, resourceIDToImages, err := rsrcHandler.GetResources(ctx, opaSessionObj, &policyIdentifier[0].Designators, progressListener, scanInfo)
resourcesMap, allResources, ksResources, excludedRulesMap, err := rsrcHandler.GetResources(ctx, opaSessionObj, &policyIdentifier[0].Designators, progressListener, scanInfo)
if err != nil {
return err
}
@@ -38,7 +38,6 @@ func CollectResources(ctx context.Context, rsrcHandler IResourceHandler, policyI
opaSessionObj.AllResources = allResources
opaSessionObj.KubescapeResource = ksResources
opaSessionObj.ExcludedRules = excludedRulesMap
opaSessionObj.ResourceIDToImageMap = resourceIDToImages
if (opaSessionObj.K8SResources == nil || len(opaSessionObj.K8SResources) == 0) && (opaSessionObj.KubescapeResource == nil || len(opaSessionObj.KubescapeResource) == 0) {
return fmt.Errorf("empty list of resources")
+1 -1
View File
@@ -11,7 +11,7 @@ import (
)
type IResourceHandler interface {
GetResources(context.Context, *cautils.OPASessionObj, *identifiers.PortalDesignator, opaprocessor.IJobProgressNotificationClient, cautils.ScanInfo) (cautils.K8SResources, map[string]workloadinterface.IMetadata, cautils.KSResources, map[string]bool, map[string][]string, error)
GetResources(context.Context, *cautils.OPASessionObj, *identifiers.PortalDesignator, opaprocessor.IJobProgressNotificationClient, cautils.ScanInfo) (cautils.K8SResources, map[string]workloadinterface.IMetadata, cautils.KSResources, map[string]bool, error)
GetClusterAPIServerInfo(ctx context.Context) *version.Info
GetWorkloadParentKind(workloadinterface.IWorkload) string
}
+16 -37
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"strings"
"github.com/armosec/armoapi-go/identifiers"
logger "github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
"github.com/kubescape/kubescape/v2/core/cautils"
@@ -20,15 +21,12 @@ import (
"github.com/kubescape/k8s-interface/k8sinterface"
"github.com/kubescape/k8s-interface/workloadinterface"
"github.com/armosec/armoapi-go/identifiers"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
k8slabels "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/dynamic"
)
type cloudResourceGetter func(string, string) (workloadinterface.IMetadata, error)
@@ -60,7 +58,7 @@ func NewK8sResourceHandler(k8s *k8sinterface.KubernetesApi, fieldSelector IField
}
}
func (k8sHandler *K8sResourceHandler) GetResources(ctx context.Context, sessionObj *cautils.OPASessionObj, designator *identifiers.PortalDesignator, progressListener opaprocessor.IJobProgressNotificationClient, scanInfo cautils.ScanInfo) (cautils.K8SResources, map[string]workloadinterface.IMetadata, cautils.KSResources, map[string]bool, map[string][]string, error) {
func (k8sHandler *K8sResourceHandler) GetResources(ctx context.Context, sessionObj *cautils.OPASessionObj, designator *identifiers.PortalDesignator, progressListener opaprocessor.IJobProgressNotificationClient, scanInfo cautils.ScanInfo) (cautils.K8SResources, map[string]workloadinterface.IMetadata, cautils.KSResources, map[string]bool, error) {
// get k8s resources
logger.L().Info("Accessing Kubernetes objects")
@@ -68,7 +66,7 @@ func (k8sHandler *K8sResourceHandler) GetResources(ctx context.Context, sessionO
workload, err := k8sHandler.findWorkloadToScan(k8sHandler.workloadIdentifier)
if err != nil {
return nil, nil, nil, nil, nil, err
return nil, nil, nil, nil, err
}
sessionObj.ScannedWorkload = workload
@@ -78,28 +76,14 @@ func (k8sHandler *K8sResourceHandler) GetResources(ctx context.Context, sessionO
queryableResources, excludedRulesMap := getQueryableResourceMapFromPolicies(k8sHandler, sessionObj.Policies, workload)
ksResourceMap := setKSResourceMap(sessionObj.Policies, resourceToControl)
// get namespace and labels from designator (ignore cluster labels)
_, namespace, labels := identifiers.DigestPortalDesignator(designator)
// map of Kubescape resources to control_ids
sessionObj.ResourceToControlsMap = resourceToControl
// pull k8s resources
k8sResourcesMap, allResources, err := k8sHandler.pullResources(queryableResources, namespace, labels)
k8sResourcesMap, allResources, err := k8sHandler.pullResources(queryableResources)
if err != nil {
cautils.StopSpinner()
return k8sResourcesMap, allResources, ksResourceMap, nil, nil, err
}
resourceIDToImages := make(map[string][]string, 0)
if scanInfo.ScanImages {
for _, workload := range allResources {
wlObj := workloadinterface.NewWorkloadObj(workload.GetObject())
containers, _ := wlObj.GetContainers()
for _, container := range containers {
resourceIDToImages[workload.GetID()] = append(resourceIDToImages[workload.GetID()], container.Image)
}
}
return k8sResourcesMap, allResources, ksResourceMap, nil, err
}
// add workload to k8s resources map (for single workload scan)
@@ -174,7 +158,7 @@ func (k8sHandler *K8sResourceHandler) GetResources(ctx context.Context, sessionO
}
}
return k8sResourcesMap, allResources, ksResourceMap, excludedRulesMap, resourceIDToImages, nil
return k8sResourcesMap, allResources, ksResourceMap, excludedRulesMap, nil
}
func (k8sHandler *K8sResourceHandler) findWorkloadToScan(workloadIdentifier *cautils.WorkloadIdentifier) (workloadinterface.IWorkload, error) {
@@ -194,7 +178,11 @@ func (k8sHandler *K8sResourceHandler) findWorkloadToScan(workloadIdentifier *cau
return nil, err
}
result, err := k8sHandler.pullSingleResource(&gvr, workloadIdentifier.Namespace, nil, getNameFieldSelector(workloadIdentifier.Name, "="))
fieldSelectors := getNameFieldSelectorString(workloadIdentifier.Name, "=")
if workloadIdentifier.Namespace != "" && k8sinterface.IsNamespaceScope(&gvr) {
fieldSelectors = combineFieldSelectors(fieldSelectors, getNamespaceFieldSelectorString(workloadIdentifier.Namespace, "="))
}
result, err := k8sHandler.pullSingleResource(&gvr, nil, fieldSelectors)
if err != nil {
return nil, fmt.Errorf("failed to get resource %s, reason: %v", workloadIdentifier.String(), err)
}
@@ -327,7 +315,7 @@ func setMapNamespaceToNumOfResources(ctx context.Context, allResources map[strin
sessionObj.SetMapNamespaceToNumberOfResources(mapNamespaceToNumberOfResources)
}
func (k8sHandler *K8sResourceHandler) pullResources(queryableResources QueryableResources, namespace string, labels map[string]string) (cautils.K8SResources, map[string]workloadinterface.IMetadata, error) {
func (k8sHandler *K8sResourceHandler) pullResources(queryableResources QueryableResources) (cautils.K8SResources, map[string]workloadinterface.IMetadata, error) {
k8sResources := queryableResources.ToK8sResourceMap()
allResources := map[string]workloadinterface.IMetadata{}
@@ -335,7 +323,7 @@ func (k8sHandler *K8sResourceHandler) pullResources(queryableResources Queryable
for _, qr := range queryableResources {
apiGroup, apiVersion, resource := k8sinterface.StringToResourceGroup(qr.GroupVersionResourceTriplet)
gvr := schema.GroupVersionResource{Group: apiGroup, Version: apiVersion, Resource: resource}
result, err := k8sHandler.pullSingleResource(&gvr, namespace, labels, qr.FieldSelectors)
result, err := k8sHandler.pullSingleResource(&gvr, nil, qr.FieldSelectors)
if err != nil {
if !strings.Contains(err.Error(), "the server could not find the requested resource") {
// handle error
@@ -379,7 +367,7 @@ func (k8sHandler *K8sResourceHandler) GetWorkloadParentKind(workload workloadint
return ""
}
func (k8sHandler *K8sResourceHandler) pullSingleResource(resource *schema.GroupVersionResource, namespace string, labels map[string]string, fields string) ([]unstructured.Unstructured, error) {
func (k8sHandler *K8sResourceHandler) pullSingleResource(resource *schema.GroupVersionResource, labels map[string]string, fields string) ([]unstructured.Unstructured, error) {
resourceList := []unstructured.Unstructured{}
// set labels
listOptions := metav1.ListOptions{}
@@ -397,21 +385,12 @@ func (k8sHandler *K8sResourceHandler) pullSingleResource(resource *schema.GroupV
}
// set dynamic object
var clientResource dynamic.ResourceInterface
if namespace != "" {
clientResource = k8sHandler.k8s.DynamicClient.Resource(*resource)
} else if k8sinterface.IsNamespaceScope(resource) {
clientResource = k8sHandler.k8s.DynamicClient.Resource(*resource).Namespace(namespace)
} else if k8sHandler.fieldSelector.GetClusterScope(resource) {
clientResource = k8sHandler.k8s.DynamicClient.Resource(*resource)
} else {
continue
}
clientResource := k8sHandler.k8s.DynamicClient.Resource(*resource)
// list resources
result, err := clientResource.List(context.Background(), listOptions)
if err != nil || result == nil {
return nil, fmt.Errorf("failed to get resource: %v, namespace: %s, labelSelector: %v, reason: %v", resource, namespace, listOptions.LabelSelector, err)
return nil, fmt.Errorf("failed to get resource: %v, labelSelector: %v, fieldSelector: %v, reason: %v", resource, listOptions.LabelSelector, listOptions.FieldSelector, err)
}
resourceList = append(resourceList, result.Items...)
@@ -133,7 +133,7 @@ func mockWorkload(apiVersion, kind, namespace, name, ownerReferenceKind string)
type ResourceHandlerMock struct {
}
func (mock *ResourceHandlerMock) GetResources(context.Context, *cautils.OPASessionObj, *armotypes.PortalDesignator, opaprocessor.IJobProgressNotificationClient) (cautils.K8SResources, map[string]workloadinterface.IMetadata, cautils.KSResources, map[string]bool, error) {
func (mock *ResourceHandlerMock) GetResources(context.Context, *cautils.OPASessionObj, opaprocessor.IJobProgressNotificationClient) (cautils.K8SResources, map[string]workloadinterface.IMetadata, cautils.KSResources, map[string]bool, error) {
return nil, nil, nil, nil, nil
}
@@ -127,6 +127,10 @@ func (pp *PrettyPrinter) ActionPrint(_ context.Context, opaSessionObj *cautils.O
}
}
if pp.scanType == cautils.ScanTypeWorkload {
cautils.InfoDisplay(pp.writer, "Workload: %s/%s/%s\n", opaSessionObj.ScannedWorkload.GetNamespace(), opaSessionObj.ScannedWorkload.GetKind(), opaSessionObj.ScannedWorkload.GetName())
}
pp.mainPrinter.PrintConfigurationsScanning(&opaSessionObj.Report.SummaryDetails, sortedControlIDs)
// When writing to Stdout, we arent really writing to an output file,
@@ -24,7 +24,7 @@ func (cp *ClusterPrinter) PrintCategoriesTables(writer io.Writer, summaryDetails
categoriesToCategoryControls := mapCategoryToSummary(summaryDetails.ListControls(), mapClusterControlsToCategories)
for _, id := range categoriesDisplayOrder {
for _, id := range clusterCategoriesDisplayOrder {
categoryControl, ok := categoriesToCategoryControls[id]
if !ok {
continue
@@ -30,7 +30,7 @@ const (
nodeEscapeCategoryID = "Cat-9"
)
var categoriesDisplayOrder = []string{
var clusterCategoriesDisplayOrder = []string{
controlPlaneCategoryID,
accessControlCategoryID,
secretsCategoryID,
@@ -38,6 +38,15 @@ var categoriesDisplayOrder = []string{
workloadsCategoryID,
}
var workloadCategoriesDisplayOrder = []string{
supplyChainCategoryID,
resourceManagementCategoryID,
storageCategoryID,
secretsCategoryID,
networkCategoryID,
nodeEscapeCategoryID,
}
var mapCategoryToType = map[string]CategoryType{
controlPlaneCategoryID: TypeStatus,
accessControlCategoryID: TypeCounting,
@@ -30,7 +30,7 @@ func (rp *RepoPrinter) PrintCategoriesTables(writer io.Writer, summaryDetails *r
categoriesToCategoryControls := mapCategoryToSummary(summaryDetails.ListControls(), mapClusterControlsToCategories)
for _, id := range categoriesDisplayOrder {
for _, id := range clusterCategoriesDisplayOrder {
categoryControl, ok := categoriesToCategoryControls[id]
if !ok {
continue
@@ -26,7 +26,7 @@ func (wp *WorkloadPrinter) PrintCategoriesTables(writer io.Writer, summaryDetail
categoriesToCategoryControls := mapCategoryToSummary(summaryDetails.ListControls(), mapWorkloadControlsToCategories)
for _, id := range categoriesDisplayOrder {
for _, id := range workloadCategoriesDisplayOrder {
categoryControl, ok := categoriesToCategoryControls[id]
if !ok {
continue
@@ -32,7 +32,7 @@ func (wp *WorkloadPrinter) printImageScanningSummary(summary *imageprinter.Image
printImageScanningSummary(wp.writer, *summary, false)
for _, img := range summary.Images {
cautils.InfoTextDisplay(wp.writer, fmt.Sprintf("Receive full report by running: 'kubescape scan image %s\n", img))
cautils.SimpleDisplay(wp.writer, fmt.Sprintf("Receive full report by running: 'kubescape scan image %s'\n", img))
}
cautils.InfoTextDisplay(wp.writer, "\n")