diff --git a/core/cautils/scaninfo.go b/core/cautils/scaninfo.go index aa747b1d..fb68ea01 100644 --- a/core/cautils/scaninfo.go +++ b/core/cautils/scaninfo.go @@ -134,6 +134,7 @@ type ScanInfo struct { OmitRawResources bool // true if omit raw resources from the output PrintAttackTree bool // true if print attack tree ScanObject *objectsenvelopes.ScanObject // identifies a single resource (k8s object) to be scanned + DeletedScanObject bool // indicates whether the ScanObject is a deleted K8S resource ScanType ScanTypes ScanImages bool ChartPath string diff --git a/core/pkg/resourcehandler/k8sresources.go b/core/pkg/resourcehandler/k8sresources.go index 11db788a..3efe0704 100644 --- a/core/pkg/resourcehandler/k8sresources.go +++ b/core/pkg/resourcehandler/k8sresources.go @@ -58,7 +58,13 @@ func (k8sHandler *K8sResourceHandler) GetResources(ctx context.Context, sessionO var err error globalFieldSelectors := getFieldSelectorFromScanInfo(scanInfo) - sessionObj.SingleResourceScan, err = k8sHandler.findScanObjectResource(scanInfo.ScanObject, globalFieldSelectors) + + if scanInfo.DeletedScanObject { + sessionObj.SingleResourceScan, err = getWorkloadFromScanObject(scanInfo.ScanObject) + } else { + sessionObj.SingleResourceScan, err = k8sHandler.findScanObjectResource(scanInfo.ScanObject, globalFieldSelectors) + } + if err != nil { return nil, nil, nil, nil, err } @@ -80,7 +86,9 @@ func (k8sHandler *K8sResourceHandler) GetResources(ctx context.Context, sessionO } // add single resource to k8s resources map (for single resource scan) - addSingleResourceToResourceMaps(k8sResourcesMap, allResources, sessionObj.SingleResourceScan) + if !scanInfo.DeletedScanObject { + addSingleResourceToResourceMaps(k8sResourcesMap, allResources, sessionObj.SingleResourceScan) + } metrics.UpdateKubernetesResourcesCount(ctx, int64(len(allResources))) numberOfWorkerNodes, err := k8sHandler.pullWorkerNodesNumber() diff --git a/core/pkg/resourcehandler/k8sresourcesutils.go b/core/pkg/resourcehandler/k8sresourcesutils.go index cfff93f6..81f08d96 100644 --- a/core/pkg/resourcehandler/k8sresourcesutils.go +++ b/core/pkg/resourcehandler/k8sresourcesutils.go @@ -1,13 +1,16 @@ package resourcehandler import ( + "fmt" "strings" "github.com/kubescape/kubescape/v2/core/cautils" + "github.com/kubescape/opa-utils/objectsenvelopes" "github.com/kubescape/opa-utils/reporthandling" "k8s.io/utils/strings/slices" "github.com/kubescape/k8s-interface/k8sinterface" + "github.com/kubescape/k8s-interface/workloadinterface" ) var ( @@ -163,3 +166,14 @@ func getFieldSelectorFromScanInfo(scanInfo *cautils.ScanInfo) IFieldSelector { return &EmptySelector{} } + +func getWorkloadFromScanObject(resource *objectsenvelopes.ScanObject) (workloadinterface.IWorkload, error) { + if resource == nil { + return nil, nil + } + obj := resource.GetObject() + if k8sinterface.IsTypeWorkload(obj) { + return workloadinterface.NewWorkloadObj(obj), nil + } + return nil, fmt.Errorf("resource %s is not a valid workload", getReadableID(resource)) +} diff --git a/core/pkg/resourcehandler/k8sresourcesutils_test.go b/core/pkg/resourcehandler/k8sresourcesutils_test.go index ab1d9586..849bf68c 100644 --- a/core/pkg/resourcehandler/k8sresourcesutils_test.go +++ b/core/pkg/resourcehandler/k8sresourcesutils_test.go @@ -2,6 +2,7 @@ package resourcehandler import ( "github.com/kubescape/kubescape/v2/core/cautils" + "github.com/kubescape/opa-utils/objectsenvelopes" "github.com/stretchr/testify/assert" "testing" @@ -19,3 +20,38 @@ func TestSsEmptyImgVulns(t *testing.T) { externalResourcesMap["bla"] = []string{"blu"} assert.Equal(t, true, isEmptyImgVulns(externalResourcesMap)) } + +func Test_getWorkloadFromScanObject(t *testing.T) { + // nil input returns nil without error + workload, err := getWorkloadFromScanObject(nil) + assert.NoError(t, err) + assert.Nil(t, workload) + + // valid input returns workload without error + workload, err = getWorkloadFromScanObject(&objectsenvelopes.ScanObject{ + ApiVersion: "apps/v1", + Kind: "Deployment", + Metadata: objectsenvelopes.ScanObjectMetadata{ + Name: "test-deployment", + Namespace: "test-ns", + }, + }) + assert.NoError(t, err) + assert.NotNil(t, workload) + assert.Equal(t, "test-ns", workload.GetNamespace()) + assert.Equal(t, "test-deployment", workload.GetName()) + assert.Equal(t, "Deployment", workload.GetKind()) + assert.Equal(t, "apps/v1", workload.GetApiVersion()) + + // invalid input returns an error + workload, err = getWorkloadFromScanObject(&objectsenvelopes.ScanObject{ + ApiVersion: "apps/v1", + // missing kind + Metadata: objectsenvelopes.ScanObjectMetadata{ + Name: "test-deployment", + Namespace: "test-ns", + }, + }) + assert.Error(t, err) + assert.Nil(t, workload) +} diff --git a/httphandler/go.mod b/httphandler/go.mod index 2b246940..2aea1479 100644 --- a/httphandler/go.mod +++ b/httphandler/go.mod @@ -14,7 +14,7 @@ require ( github.com/kubescape/go-logger v0.0.20 github.com/kubescape/k8s-interface v0.0.142 github.com/kubescape/kubescape/v2 v2.0.0-00010101000000-000000000000 - github.com/kubescape/opa-utils v0.0.267 + github.com/kubescape/opa-utils v0.0.268-0.20230911064554-dda35b8c0d52 github.com/stretchr/testify v1.8.4 go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.38.0 go.opentelemetry.io/otel v1.16.0 diff --git a/httphandler/go.sum b/httphandler/go.sum index 11d5813a..4e13bfcf 100644 --- a/httphandler/go.sum +++ b/httphandler/go.sum @@ -1298,8 +1298,8 @@ github.com/kubescape/go-logger v0.0.20 h1:ZU3T6Za7maCiChdoTrqpD6TI11DGJwd9xU/TFt github.com/kubescape/go-logger v0.0.20/go.mod h1:BAWhQMYc/gnC5wMtPvc9Z4VXFqykFFMaXaPkq0+txBY= github.com/kubescape/k8s-interface v0.0.142 h1:kL8D/2s+GNEZlp50rTNDLe6dhSzHAXMOQweyJdSWkVk= github.com/kubescape/k8s-interface v0.0.142/go.mod h1:5sz+5Cjvo98lTbTVDiDA4MmlXxeHSVMW/wR0V3hV4K8= -github.com/kubescape/opa-utils v0.0.267 h1:qzINBGsVOTKeLAIj1YfaYdV93FsSRriWdiN0JXJwD/o= -github.com/kubescape/opa-utils v0.0.267/go.mod h1:95JkuIOfClgLc+DyGb2mDvefRW0STkZe4L2z6AaZJlQ= +github.com/kubescape/opa-utils v0.0.268-0.20230911064554-dda35b8c0d52 h1:F/kXFfNarA2GhZ0KvH3v+9/qzv7p9JsJHQZ7Gdlfy00= +github.com/kubescape/opa-utils v0.0.268-0.20230911064554-dda35b8c0d52/go.mod h1:95JkuIOfClgLc+DyGb2mDvefRW0STkZe4L2z6AaZJlQ= 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.291-rc.0 h1:DztPS3NSKfiltO1wZvxRjuu5c99c6+dEgfTs6DcsVa8= diff --git a/httphandler/handlerequests/v1/datastructuremethods.go b/httphandler/handlerequests/v1/datastructuremethods.go index 0ab5677a..6b7df860 100644 --- a/httphandler/handlerequests/v1/datastructuremethods.go +++ b/httphandler/handlerequests/v1/datastructuremethods.go @@ -61,6 +61,10 @@ func ToScanInfo(scanRequest *utilsmetav1.PostScanRequest) *cautils.ScanInfo { scanInfo.ScanObject = scanRequest.ScanObject } + if scanRequest.DeletedScanObject != nil { + scanInfo.DeletedScanObject = *scanRequest.DeletedScanObject + } + return scanInfo }