Skip to content

Commit

Permalink
ISSUE-1830-2: Adding Stop scan related changes for Vulnerability,
Browse files Browse the repository at this point in the history
Compliance and Cloud compliance scans
  • Loading branch information
varunsharma0286 committed Sep 19, 2023
1 parent 9122e3c commit b0a459c
Show file tree
Hide file tree
Showing 20 changed files with 354 additions and 138 deletions.
47 changes: 41 additions & 6 deletions deepfence_bootstrapper/controls/controls.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package controls

import (
"errors"
"fmt"
"os/exec"
"strings"
Expand Down Expand Up @@ -43,7 +44,9 @@ func SetClusterAgentControls(k8sClusterName string) {
func(req ctl.SendAgentDiagnosticLogsRequest) error {
log.Info().Msg("Generate Cluster Agent Diagnostic Logs")
return SendAgentDiagnosticLogs(req,
[]string{"/var/log/supervisor", "/var/log/fenced/compliance-scan-logs", "/var/log/deepfenced"},
[]string{"/var/log/supervisor",
"/var/log/fenced/compliance-scan-logs",
"/var/log/deepfenced"},
[]string{})
})
if err != nil {
Expand Down Expand Up @@ -81,11 +84,16 @@ func SetAgentControls() {
if err != nil {
return err
}
err = scanner.RunComplianceScan()
if err != nil {
log.Error().Msgf("Error from scan: %+v", err)
return err
}

log.Info().Msg("StartComplianceScan Starting")
//We need to run this in a goroutine else it will block the
//fetch and execution of controls
go func() {
err := scanner.RunComplianceScan()
if err != nil {
log.Error().Msgf("Error from RunComplianceScan: %+v", err)
}
}()
return nil
})
if err != nil {
Expand Down Expand Up @@ -155,4 +163,31 @@ func SetAgentControls() {
log.Error().Msgf("set controls: %v", err)
}

err = router.RegisterControl(ctl.StopVulnerabilityScan,
func(req ctl.StopVulnerabilityScanRequest) error {
log.Info().Msg("StopVulnerabilityScanRequest called")
return router.StopVulnerabilityScan(req)
})
if err != nil {
log.Error().Msgf("set controls: %v", err)
}

err = router.RegisterControl(ctl.StopComplianceScan,
func(req ctl.StopComplianceScanRequest) error {
log.Info().Msg("StopComplianceScanRequest called")
scanId, ok := req.BinArgs["scan_id"]
var err error
if ok {
retVal := linuxScanner.StopScan(scanId)
if retVal == false {
err = errors.New("Failed to stop scan")
}
} else {
err = errors.New("Missing scan id in the StopComplianceScanRequest")
}
return err
})
if err != nil {
log.Error().Msgf("set controls: %v", err)
}
}
13 changes: 12 additions & 1 deletion deepfence_bootstrapper/router/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,18 @@ const (
var controls map[ctl.ActionID]func(req []byte) error
var controls_guard sync.RWMutex

func RegisterControl[T ctl.StartVulnerabilityScanRequest | ctl.StartSecretScanRequest | ctl.StartComplianceScanRequest | ctl.StartMalwareScanRequest | ctl.StartAgentUpgradeRequest | ctl.SendAgentDiagnosticLogsRequest | ctl.DisableAgentPluginRequest | ctl.EnableAgentPluginRequest | ctl.StopSecretScanRequest | ctl.StopMalwareScanRequest](id ctl.ActionID, callback func(req T) error) error {
func RegisterControl[T ctl.StartVulnerabilityScanRequest |
ctl.StartSecretScanRequest |
ctl.StartComplianceScanRequest |
ctl.StartMalwareScanRequest |
ctl.StartAgentUpgradeRequest |
ctl.SendAgentDiagnosticLogsRequest |
ctl.DisableAgentPluginRequest |
ctl.EnableAgentPluginRequest |
ctl.StopSecretScanRequest |
ctl.StopMalwareScanRequest |
ctl.StopVulnerabilityScanRequest |
ctl.StopComplianceScanRequest](id ctl.ActionID, callback func(req T) error) error {

controls_guard.Lock()
defer controls_guard.Unlock()
Expand Down
17 changes: 17 additions & 0 deletions deepfence_bootstrapper/router/generate_sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package router
import (
"context"
"errors"
"fmt"
"os"

ctl "github.com/deepfence/ThreatMapper/deepfence_utils/controls"
Expand Down Expand Up @@ -172,3 +173,19 @@ func GetPackageScannerJobCount() int32 {
}
return jobReport.RunningJobs
}

func StopVulnerabilityScan(req ctl.StopVulnerabilityScanRequest) error {
fmt.Printf("Stop Vulnerability Scan : %v\n", req)
conn, err := createPackageScannerConn()
if err != nil {
fmt.Printf("StopVulnerabilityScanJob::error in creating Vulnerability scanner client: %s\n", err.Error())
return err
}
defer conn.Close()
client := pb.NewScannersClient(conn)
var greq pb.StopScanRequest
greq.ScanId = req.BinArgs["scan_id"]

_, err = client.StopScan(context.Background(), &greq)
return err
}
21 changes: 21 additions & 0 deletions deepfence_ctl/cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,27 @@ var scanStopSubCmd = &cobra.Command{
ScanType: "MalwareScan",
})
res, err = http.Client().MalwareScanAPI.StopMalwareScanExecute(req)
case "vulnerability":
req := http.Client().VulnerabilityAPI.StopVulnerabilityScan(context.Background())
req = req.ModelStopScanRequest(deepfence_server_client.ModelStopScanRequest{
ScanId: scan_id,
ScanType: "VulnerabilityScan",
})
res, err = http.Client().VulnerabilityAPI.StopVulnerabilityScanExecute(req)
case "compliance":
req := http.Client().ComplianceAPI.StopComplianceScan(context.Background())
req = req.ModelStopScanRequest(deepfence_server_client.ModelStopScanRequest{
ScanId: scan_id,
ScanType: "ComplianceScan",
})
res, err = http.Client().ComplianceAPI.StopComplianceScanExecute(req)
case "cloudcompliance":
req := http.Client().ComplianceAPI.StopComplianceScan(context.Background())
req = req.ModelStopScanRequest(deepfence_server_client.ModelStopScanRequest{
ScanId: scan_id,
ScanType: "CloudComplianceScan",
})
res, err = http.Client().ComplianceAPI.StopComplianceScanExecute(req)
default:
log.Fatal().Msg("Unsupported")
}
Expand Down
4 changes: 2 additions & 2 deletions deepfence_server/apiDocs/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,10 +489,10 @@ func (d *OpenApiDocs) AddScansOperations() {
// Stop scan
d.AddOperation("stopVulnerabilityScan", http.MethodPost, "/deepfence/scan/stop/vulnerability",
"Stop Vulnerability Scan", "Stop Vulnerability Scan on agent or registry",
http.StatusAccepted, []string{tagVulnerability}, bearerToken, new(VulnerabilityScanTriggerReq), nil)
http.StatusAccepted, []string{tagVulnerability}, bearerToken, new(StopScanRequest), nil)
d.AddOperation("stopComplianceScan", http.MethodPost, "/deepfence/scan/stop/compliance",
"Stop Compliance Scan", "Stop Compliance Scan on agent or registry",
http.StatusAccepted, []string{tagCompliance}, bearerToken, new(ComplianceScanTriggerReq), nil)
http.StatusAccepted, []string{tagCompliance}, bearerToken, new(StopScanRequest), nil)
d.AddOperation("stopMalwareScan", http.MethodPost, "/deepfence/scan/stop/malware",
"Stop Malware Scan", "Stop Malware Scan on agent or registry",
http.StatusAccepted, []string{tagMalwareScan}, bearerToken, new(StopScanRequest), nil)
Expand Down
4 changes: 4 additions & 0 deletions deepfence_server/controls/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ func ExtractStoppingAgentScans(ctx context.Context, nodeId string,
action.ID = controls.StopSecretScan
case controls.StartMalwareScan:
action.ID = controls.StopMalwareScan
case controls.StartVulnerabilityScan:
action.ID = controls.StopVulnerabilityScan
case controls.StartComplianceScan:
action.ID = controls.StopComplianceScan
default:
log.Info().Msgf("Stop functionality not implemented for action: %d", action.ID)
continue
Expand Down
18 changes: 10 additions & 8 deletions deepfence_server/handler/cloud_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ func (h *Handler) RegisterCloudNodeAccountHandler(w http.ResponseWriter, r *http
log.Error().Msgf("Error getting controls for compliance type: %+v", scan.BenchmarkTypes)
}
scanDetail := model.CloudComplianceScanDetails{
ScanId: scan.ScanId,
ScanTypes: scan.BenchmarkTypes,
AccountId: monitoredAccountId,
Benchmarks: benchmarks,
ScanId: scan.ScanId,
ScanTypes: scan.BenchmarkTypes,
AccountId: monitoredAccountId,
Benchmarks: benchmarks,
StopRequested: scan.StopRequested,
}
scanList[scan.ScanId] = scanDetail
}
Expand Down Expand Up @@ -125,10 +126,11 @@ func (h *Handler) RegisterCloudNodeAccountHandler(w http.ResponseWriter, r *http
log.Error().Msgf("Error getting controls for compliance type: %+v", scan.BenchmarkTypes)
}
scanDetail := model.CloudComplianceScanDetails{
ScanId: scan.ScanId,
ScanTypes: scan.BenchmarkTypes,
AccountId: req.CloudAccount,
Benchmarks: benchmarks,
ScanId: scan.ScanId,
ScanTypes: scan.BenchmarkTypes,
AccountId: req.CloudAccount,
Benchmarks: benchmarks,
StopRequested: scan.StopRequested,
}
scanList[scan.ScanId] = scanDetail
}
Expand Down
44 changes: 26 additions & 18 deletions deepfence_server/handler/scan_reports.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,19 +528,19 @@ func (h *Handler) SendScanStatus(
}

func (h *Handler) StopVulnerabilityScanHandler(w http.ResponseWriter, r *http.Request) {
stopScan(w, r, ctl.StartVulnerabilityScan)
h.stopScan(w, r, "StopVulnerabilityScan")
}

func (h *Handler) StopSecretScanHandler(w http.ResponseWriter, r *http.Request) {
h.stopSecretScan(w, r)
h.stopScan(w, r, "StopSecretScan")
}

func (h *Handler) StopComplianceScanHandler(w http.ResponseWriter, r *http.Request) {
stopScan(w, r, ctl.StartComplianceScan)
h.stopScan(w, r, "StopComplianceScan")
}

func (h *Handler) StopMalwareScanHandler(w http.ResponseWriter, r *http.Request) {
h.stopMalwareScan(w, r)
h.stopScan(w, r, "StopMalwareScan")
}

func (h *Handler) IngestCloudResourcesReportHandler(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -784,18 +784,13 @@ func ingest_scan_report_kafka[T any](
httpext.JSON(respWrite, http.StatusOK, map[string]string{"status": "ok"})
}

func stopScan(w http.ResponseWriter, r *http.Request, action ctl.ActionID) {

}

func (h *Handler) stopSecretScan(w http.ResponseWriter, r *http.Request) {
func (h *Handler) stopComplianceScan(w http.ResponseWriter, r *http.Request) {
// Stopping scan is on best-effort basis, not guaranteed

defer r.Body.Close()
var req model.StopScanRequest
err := httpext.DecodeJSON(r, httpext.NoQueryParams, MaxPostRequestSize, &req)
if err != nil {
log.Error().Msgf("Failed to DecodeJSON: %v", err)
log.Error().Msgf("StopComplianceScan Failed to DecodeJSON: %v", err)
h.respondError(err, w)
return
}
Expand All @@ -807,11 +802,16 @@ func (h *Handler) stopSecretScan(w http.ResponseWriter, r *http.Request) {
return
}

log.Info().Msgf("StopSecretScan request, type: %s, scanid: %s", req.ScanType, req.ScanID)
log.Info().Msgf("StopComplianceScan request, type: %s, scanid: %s", req.ScanType, req.ScanID)

if req.ScanType == "CloudComplianceScan" {
err = reporters_scan.StopCloudComplianceScan(r.Context(), req.ScanType, req.ScanID)
} else {
err = reporters_scan.StopScan(r.Context(), req.ScanType, req.ScanID)
}

err = reporters_scan.StopScan(r.Context(), req.ScanType, req.ScanID)
if err != nil {
log.Error().Msgf("Error in StopScan: %v", err)
log.Error().Msgf("Error in StopComplianceScan: %v", err)
h.respondError(&ValidatorError{err: err}, w)
return
}
Expand All @@ -821,13 +821,13 @@ func (h *Handler) stopSecretScan(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusAccepted)
}

func (h *Handler) stopMalwareScan(w http.ResponseWriter, r *http.Request) {
func (h *Handler) stopScan(w http.ResponseWriter, r *http.Request, tag string) {
// Stopping scan is on best-effort basis, not guaranteed
defer r.Body.Close()
var req model.StopScanRequest
err := httpext.DecodeJSON(r, httpext.NoQueryParams, MaxPostRequestSize, &req)
if err != nil {
log.Error().Msgf("StopMalwareScan Failed to DecodeJSON: %v", err)
log.Error().Msgf("%s Failed to DecodeJSON: %v", tag, err)
h.respondError(err, w)
return
}
Expand All @@ -839,9 +839,16 @@ func (h *Handler) stopMalwareScan(w http.ResponseWriter, r *http.Request) {
return
}

log.Info().Msgf("StopMalwareScan request, type: %s, scanid: %s", req.ScanType, req.ScanID)
if req.ScanType == "CloudComplianceScan" {
log.Info().Msgf("CloudComplianceScan request, type: %s, scanid: %s",
req.ScanType, req.ScanID)
err = reporters_scan.StopCloudComplianceScan(r.Context(), req.ScanType, req.ScanID)
} else {
log.Info().Msgf("%s request, type: %s, scanid: %s",
tag, req.ScanType, req.ScanID)
err = reporters_scan.StopScan(r.Context(), req.ScanType, req.ScanID)
}

err = reporters_scan.StopScan(r.Context(), req.ScanType, req.ScanID)
if err != nil {
log.Error().Msgf("Error in StopScan: %v", err)
h.respondError(&ValidatorError{err: err}, w)
Expand Down Expand Up @@ -2119,6 +2126,7 @@ func StartMultiCloudComplianceScan(ctx context.Context, reqs []model.NodeIdentif
reqs[0].NodeType)

if err != nil {
log.Info().Msgf("Error in AddNewCloudComplianceScan:%v", err)
if e, is := err.(*ingesters.AlreadyRunningScanError); is {
scanIds = append(scanIds, e.ScanId)
continue
Expand Down
2 changes: 2 additions & 0 deletions deepfence_server/ingesters/scan_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,14 @@ func AddNewCloudComplianceScan(tx WriteDBTransaction,
OPTIONAL MATCH (n:%s)-[:SCANNED]->(m)
WHERE NOT n.status = $complete
AND NOT n.status = $failed
AND NOT n.status = $cancelled
AND n.benchmark_types = $benchmark_types
RETURN n.node_id, m.agent_running`, neo4jNodeType, scanType),
map[string]interface{}{
"node_id": nodeId,
"complete": utils.SCAN_STATUS_SUCCESS,
"failed": utils.SCAN_STATUS_FAILED,
"cancelled": utils.SCAN_STATUS_CANCELLED,
"benchmark_types": benchmarkTypes,
})
if err != nil {
Expand Down
9 changes: 5 additions & 4 deletions deepfence_server/model/cloud_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,11 @@ type CloudComplianceBenchmark struct {
}

type CloudComplianceScanDetails struct {
ScanId string `json:"scan_id"`
ScanTypes []string `json:"scan_types"`
AccountId string `json:"account_id"`
Benchmarks []CloudComplianceBenchmark `json:"benchmarks"`
ScanId string `json:"scan_id"`
ScanTypes []string `json:"scan_types"`
AccountId string `json:"account_id"`
Benchmarks []CloudComplianceBenchmark `json:"benchmarks"`
StopRequested bool `json:"stop_requested"`
}

type CloudNodeCloudtrailTrail struct {
Expand Down
1 change: 1 addition & 0 deletions deepfence_server/model/scans.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ type ScanInfo struct {
NodeType string `json:"node_type" required:"true"`
SeverityCounts map[string]int32 `json:"severity_counts" required:"true"`
NodeName string `json:"node_name" required:"true"`
StopRequested bool `json:"stop_requested"`
}

type ComplianceScanInfo struct {
Expand Down
Loading

0 comments on commit b0a459c

Please sign in to comment.