Compare commits

..

1 Commits

Author SHA1 Message Date
David Wertenteil
5a83f38bca send prometheus triggering to queue 2022-05-22 09:57:30 +03:00
4 changed files with 45 additions and 33 deletions

View File

@@ -7,48 +7,56 @@ import (
"path/filepath"
"github.com/armosec/kubescape/v2/core/cautils"
"github.com/armosec/kubescape/v2/core/cautils/logger"
"github.com/armosec/kubescape/v2/core/cautils/logger/helpers"
"github.com/armosec/kubescape/v2/core/core"
utilsapisv1 "github.com/armosec/opa-utils/httpserver/apis/v1"
"github.com/google/uuid"
)
// Metrics http listener for prometheus support
func (handler *HTTPHandler) Metrics(w http.ResponseWriter, r *http.Request) {
if handler.state.len() > 0 { // if already scanning the cluster
message := fmt.Sprintf("scan '%s' in action", handler.state.getLatestID())
logger.L().Info("server is busy", helpers.String("message", message), helpers.Time())
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte(message))
return
}
scanID := uuid.NewString()
handler.state.setBusy(scanID)
defer handler.state.setNotBusy(scanID)
resultsFile := filepath.Join(OutputDir, scanID)
scanInfo := getPrometheusDefaultScanCommand(scanID, resultsFile)
// trigger scanning
logger.L().Info(scanID, helpers.String("action", "triggering scan"), helpers.Time())
scanParams := &scanRequestParams{
scanQueryParams: &ScanQueryParams{
ReturnResults: true,
KeepResults: false,
},
scanInfo: scanInfo,
scanID: scanID,
}
ks := core.NewKubescape()
results, err := ks.Scan(getPrometheusDefaultScanCommand(scanID, resultsFile))
if err != nil {
handler.scanResponseChan.set(scanID) // add scan to channel
defer handler.scanResponseChan.delete(scanID)
// send to scan queue
handler.scanRequestChan <- scanParams
// wait for scan to complete
results := <-handler.scanResponseChan.get(scanID)
defer removeResultsFile(scanID) // remove json format results file
defer os.Remove(resultsFile) // remove prometheus format results file
// handle response
if results.Type == utilsapisv1.ErrorScanResponseType {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("failed to complete scan. reason: %s", err.Error())))
w.Write(responseToBytes(results))
return
}
results.HandleResults()
logger.L().Info(scanID, helpers.String("action", "done scanning"), helpers.Time())
// read prometheus format results file
f, err := os.ReadFile(resultsFile)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("failed read results from file. reason: %s", err.Error())))
results.Type = utilsapisv1.ErrorScanResponseType
results.Response = fmt.Sprintf("failed read results from file. reason: %s", err.Error())
w.Write(responseToBytes(results))
return
}
os.Remove(resultsFile)
w.WriteHeader(http.StatusOK)
w.Write(f)

View File

@@ -7,6 +7,7 @@ import (
"net/http"
"sync"
"github.com/armosec/kubescape/v2/core/cautils"
"github.com/armosec/kubescape/v2/core/cautils/logger"
"github.com/armosec/kubescape/v2/core/cautils/logger/helpers"
utilsmetav1 "github.com/armosec/opa-utils/httpserver/meta/v1"
@@ -71,9 +72,9 @@ type StatusQueryParams struct {
// scanRequestParams params passed to channel
type scanRequestParams struct {
scanRequest *utilsmetav1.PostScanRequest // request as received from api
scanQueryParams *ScanQueryParams // request as received from api
scanID string // generated scan ID
scanInfo *cautils.ScanInfo // request as received from api
scanQueryParams *ScanQueryParams // request as received from api
scanID string // generated scan ID
}
func getScanParamsFromRequest(r *http.Request, scanID string) (*scanRequestParams, error) {
@@ -99,9 +100,11 @@ func getScanParamsFromRequest(r *http.Request, scanID string) (*scanRequestParam
return scanRequestParams, fmt.Errorf("failed to parse request payload, reason: %s", err.Error())
}
scanInfo := getScanCommand(scanRequest, scanID)
scanRequestParams.scanID = scanID
scanRequestParams.scanQueryParams = scanQueryParams
scanRequestParams.scanRequest = scanRequest
scanRequestParams.scanInfo = scanInfo
return scanRequestParams, nil
}

View File

@@ -39,9 +39,9 @@ func TestGetScanParamsFromRequest(t *testing.T) {
assert.Equal(t, scanID, req.scanID)
assert.True(t, req.scanQueryParams.KeepResults)
assert.True(t, req.scanQueryParams.ReturnResults)
assert.True(t, *req.scanRequest.HostScanner)
assert.True(t, *req.scanRequest.Submit)
assert.Equal(t, "aaaaaaaaaa", req.scanRequest.Account)
assert.True(t, req.scanInfo.HostSensorEnabled.GetBool())
assert.True(t, req.scanInfo.Submit)
assert.Equal(t, "aaaaaaaaaa", req.scanInfo.Account)
}
{
@@ -69,8 +69,8 @@ func TestGetScanParamsFromRequest(t *testing.T) {
assert.Equal(t, scanID, req.scanID)
assert.False(t, req.scanQueryParams.KeepResults)
assert.False(t, req.scanQueryParams.ReturnResults)
assert.False(t, *req.scanRequest.HostScanner)
assert.False(t, *req.scanRequest.Submit)
assert.Equal(t, "aaaaaaaaaa", req.scanRequest.Account)
assert.False(t, req.scanInfo.HostSensorEnabled.GetBool())
assert.False(t, req.scanInfo.Submit)
assert.Equal(t, "aaaaaaaaaa", req.scanInfo.Account)
}
}

View File

@@ -23,10 +23,12 @@ func (handler *HTTPHandler) executeScan() {
for {
scanReq := <-handler.scanRequestChan
logger.L().Info("triggering scan", helpers.String("scanID", scanReq.scanID))
response := &utilsmetav1.Response{}
logger.L().Info("scan triggered", helpers.String("ID", scanReq.scanID))
results, err := scan(scanReq.scanRequest, scanReq.scanID)
results, err := scan(scanReq.scanInfo, scanReq.scanID)
if err != nil {
logger.L().Error("scanning failed", helpers.String("ID", scanReq.scanID), helpers.Error(err))
if scanReq.scanQueryParams.ReturnResults {
@@ -48,8 +50,7 @@ func (handler *HTTPHandler) executeScan() {
}
}
func scan(scanRequest *utilsmetav1.PostScanRequest, scanID string) (*reporthandlingv2.PostureReport, error) {
scanInfo := getScanCommand(scanRequest, scanID)
func scan(scanInfo *cautils.ScanInfo, scanID string) (*reporthandlingv2.PostureReport, error) {
ks := core.NewKubescape()
result, err := ks.Scan(scanInfo)