diff --git a/go.mod b/go.mod index 4a2e717f..27cf45ee 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/armosec/armoapi-go v0.0.67 github.com/armosec/go-git-url v0.0.4 github.com/armosec/k8s-interface v0.0.70 - github.com/armosec/opa-utils v0.0.135 + github.com/armosec/opa-utils v0.0.136 github.com/armosec/rbac-utils v0.0.14 github.com/armosec/utils-go v0.0.5 github.com/armosec/utils-k8s-go v0.0.6 diff --git a/go.sum b/go.sum index d3663e3f..5e79dfe4 100644 --- a/go.sum +++ b/go.sum @@ -122,8 +122,8 @@ github.com/armosec/k8s-interface v0.0.37/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2 github.com/armosec/k8s-interface v0.0.70 h1:NU3UIaNl7H3hsRecwggiaQbZXTwXtOKg3GOBjq6/XJw= github.com/armosec/k8s-interface v0.0.70/go.mod h1:8NX4xWXh8mwW7QyZdZea1czNdM2azCK9BbUNmiZYXW0= github.com/armosec/opa-utils v0.0.64/go.mod h1:6tQP8UDq2EvEfSqh8vrUdr/9QVSCG4sJfju1SXQOn4c= -github.com/armosec/opa-utils v0.0.135 h1:7JMHGKMD13XWwwd4g11tw6T9C4BRPifDiqdeDJEz638= -github.com/armosec/opa-utils v0.0.135/go.mod h1:mCFQzz4E227f7V2jQVQ9XCivkNNK3UWCTaZ0HE5rBWk= +github.com/armosec/opa-utils v0.0.136 h1:WOflXgweEUZAbLwyB18x8cbIftGhp2M2UngGxIvQEPY= +github.com/armosec/opa-utils v0.0.136/go.mod h1:mCFQzz4E227f7V2jQVQ9XCivkNNK3UWCTaZ0HE5rBWk= github.com/armosec/rbac-utils v0.0.1/go.mod h1:pQ8CBiij8kSKV7aeZm9FMvtZN28VgA7LZcYyTWimq40= github.com/armosec/rbac-utils v0.0.14 h1:CKYKcgqJEXWF2Hen/B1pVGtS3nDAG1wp9dDv6oNtq90= github.com/armosec/rbac-utils v0.0.14/go.mod h1:Ex/IdGWhGv9HZq6Hs8N/ApzCKSIvpNe/ETqDfnuyah0= diff --git a/httphandler/go.mod b/httphandler/go.mod index e1becf30..5e7a0f3f 100644 --- a/httphandler/go.mod +++ b/httphandler/go.mod @@ -6,7 +6,7 @@ replace github.com/armosec/kubescape/v2 => ../ require ( github.com/armosec/kubescape/v2 v2.0.0-00010101000000-000000000000 - github.com/armosec/opa-utils v0.0.135 + github.com/armosec/opa-utils v0.0.136 github.com/armosec/utils-go v0.0.5 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 diff --git a/httphandler/go.sum b/httphandler/go.sum index 7946e491..30c4dcef 100644 --- a/httphandler/go.sum +++ b/httphandler/go.sum @@ -122,9 +122,8 @@ github.com/armosec/k8s-interface v0.0.37/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2 github.com/armosec/k8s-interface v0.0.70 h1:NU3UIaNl7H3hsRecwggiaQbZXTwXtOKg3GOBjq6/XJw= github.com/armosec/k8s-interface v0.0.70/go.mod h1:8NX4xWXh8mwW7QyZdZea1czNdM2azCK9BbUNmiZYXW0= github.com/armosec/opa-utils v0.0.64/go.mod h1:6tQP8UDq2EvEfSqh8vrUdr/9QVSCG4sJfju1SXQOn4c= -github.com/armosec/opa-utils v0.0.134/go.mod h1:mCFQzz4E227f7V2jQVQ9XCivkNNK3UWCTaZ0HE5rBWk= -github.com/armosec/opa-utils v0.0.135 h1:7JMHGKMD13XWwwd4g11tw6T9C4BRPifDiqdeDJEz638= -github.com/armosec/opa-utils v0.0.135/go.mod h1:mCFQzz4E227f7V2jQVQ9XCivkNNK3UWCTaZ0HE5rBWk= +github.com/armosec/opa-utils v0.0.136 h1:WOflXgweEUZAbLwyB18x8cbIftGhp2M2UngGxIvQEPY= +github.com/armosec/opa-utils v0.0.136/go.mod h1:mCFQzz4E227f7V2jQVQ9XCivkNNK3UWCTaZ0HE5rBWk= github.com/armosec/rbac-utils v0.0.1/go.mod h1:pQ8CBiij8kSKV7aeZm9FMvtZN28VgA7LZcYyTWimq40= github.com/armosec/rbac-utils v0.0.14 h1:CKYKcgqJEXWF2Hen/B1pVGtS3nDAG1wp9dDv6oNtq90= github.com/armosec/rbac-utils v0.0.14/go.mod h1:Ex/IdGWhGv9HZq6Hs8N/ApzCKSIvpNe/ETqDfnuyah0= diff --git a/httphandler/handlerequests/v1/requestshandler.go b/httphandler/handlerequests/v1/requestshandler.go index e8a81f01..8bbef8a7 100644 --- a/httphandler/handlerequests/v1/requestshandler.go +++ b/httphandler/handlerequests/v1/requestshandler.go @@ -7,6 +7,7 @@ import ( "net/http" "sync" + utilsapisv1 "github.com/armosec/opa-utils/httpserver/apis/v1" utilsmetav1 "github.com/armosec/opa-utils/httpserver/meta/v1" "github.com/armosec/kubescape/v2/core/cautils/logger" @@ -26,20 +27,12 @@ func NewHTTPHandler() *HTTPHandler { state: newServerState(), } } + func (handler *HTTPHandler) Scan(w http.ResponseWriter, r *http.Request) { response := utilsmetav1.Response{} w.Header().Set("Content-Type", "application/json") - defer func() { - if err := recover(); err != nil { - handler.state.setNotBusy() - logger.L().Error("Scan recover", helpers.Error(fmt.Errorf("%v", err))) - w.WriteHeader(http.StatusInternalServerError) - response.Response = []byte(fmt.Sprintf("%v", err)) - response.Type = utilsmetav1.ErrorScanResponseType - w.Write(responseToBytes(&response)) - } - }() + defer handler.recover(w) defer r.Body.Close() @@ -67,24 +60,16 @@ func (handler *HTTPHandler) Scan(w http.ResponseWriter, r *http.Request) { scanID := uuid.NewString() handler.state.setID(scanID) response.ID = scanID - response.Type = utilsmetav1.IDScanResponseType + response.Type = utilsapisv1.IDScanResponseType readBuffer, err := ioutil.ReadAll(r.Body) if err != nil { - defer handler.state.setNotBusy() - w.WriteHeader(http.StatusBadRequest) - response.Response = []byte(fmt.Sprintf("failed to read request body, reason: %s", err.Error())) - response.Type = utilsmetav1.ErrorScanResponseType - w.Write(responseToBytes(&response)) + handler.writeError(w, fmt.Errorf("failed to read request body, reason: %s", err.Error())) return } scanRequest := utilsmetav1.PostScanRequest{} if err := json.Unmarshal(readBuffer, &scanRequest); err != nil { - defer handler.state.setNotBusy() - w.WriteHeader(http.StatusBadRequest) - response.Response = []byte(fmt.Sprintf("failed to parse request payload, reason: %s", err.Error())) - response.Type = utilsmetav1.ErrorScanResponseType - w.Write(responseToBytes(&response)) + handler.writeError(w, fmt.Errorf("failed to parse request payload, reason: %s", err.Error())) return } @@ -107,14 +92,14 @@ func (handler *HTTPHandler) Scan(w http.ResponseWriter, r *http.Request) { if err != nil { logger.L().Error("scanning failed", helpers.String("ID", scanID), helpers.Error(err)) if returnResults { - response.Type = utilsmetav1.ErrorScanResponseType + response.Type = utilsapisv1.ErrorScanResponseType response.Response = []byte(err.Error()) statusCode = http.StatusInternalServerError } } else { logger.L().Success("done scanning", helpers.String("ID", scanID)) if returnResults { - response.Type = utilsmetav1.ResultsV1ScanResponseType + response.Type = utilsapisv1.ResultsV1ScanResponseType response.Response = results wg.Done() } @@ -135,16 +120,7 @@ func (handler *HTTPHandler) Results(w http.ResponseWriter, r *http.Request) { response := utilsmetav1.Response{} w.Header().Set("Content-Type", "application/json") - defer func() { - if err := recover(); err != nil { - handler.state.setNotBusy() - logger.L().Error("Results recover", helpers.Error(fmt.Errorf("%v", err))) - w.WriteHeader(http.StatusInternalServerError) - response.Response = []byte(fmt.Sprintf("%v", err)) - response.Type = utilsmetav1.ErrorScanResponseType - w.Write(responseToBytes(&response)) - } - }() + defer handler.recover(w) defer r.Body.Close() @@ -156,7 +132,7 @@ func (handler *HTTPHandler) Results(w http.ResponseWriter, r *http.Request) { logger.L().Info("empty scan ID") w.WriteHeader(http.StatusBadRequest) // Should we return ok? response.Response = []byte("latest scan not found. trigger again") - response.Type = utilsmetav1.ErrorScanResponseType + response.Type = utilsapisv1.ErrorScanResponseType w.Write(responseToBytes(&response)) return } @@ -217,3 +193,24 @@ func responseToBytes(res *utilsmetav1.Response) []byte { b, _ := json.Marshal(res) return b } + +func (handler *HTTPHandler) recover(w http.ResponseWriter) { + response := utilsmetav1.Response{} + if err := recover(); err != nil { + handler.state.setNotBusy() + logger.L().Error("recover", helpers.Error(fmt.Errorf("%v", err))) + w.WriteHeader(http.StatusInternalServerError) + response.Response = []byte(fmt.Sprintf("%v", err)) + response.Type = utilsapisv1.ErrorScanResponseType + w.Write(responseToBytes(&response)) + } +} + +func (handler *HTTPHandler) writeError(w http.ResponseWriter, err error) { + response := utilsmetav1.Response{} + w.WriteHeader(http.StatusBadRequest) + response.Response = []byte(err.Error()) + response.Type = utilsapisv1.ErrorScanResponseType + w.Write(responseToBytes(&response)) + handler.state.setNotBusy() +} diff --git a/httphandler/handlerequests/v1/requestshandlerutils.go b/httphandler/handlerequests/v1/requestshandlerutils.go index 6f80eae6..15b4118c 100644 --- a/httphandler/handlerequests/v1/requestshandlerutils.go +++ b/httphandler/handlerequests/v1/requestshandlerutils.go @@ -19,20 +19,14 @@ func scan(scanRequest *utilsmetav1.PostScanRequest, scanID string) ([]byte, erro ks := core.NewKubescape() result, err := ks.Scan(scanInfo) if err != nil { - f, e := os.Open(filepath.Join(FailedOutputDir, scanID)) - if e != nil { - return []byte{}, fmt.Errorf("failed to scan. reason: '%s'. failed to save error in file. reason: %s", err.Error(), e.Error()) - } - defer f.Close() - f.Write([]byte(e.Error())) - + return []byte{}, writeScanErrorToFile(err, scanID) } if err := result.HandleResults(); err != nil { return nil, err } b, err := result.ToJson() if err != nil { - err = fmt.Errorf("failed to parse results to json, reason: %s", err.Error()) + err = fmt.Errorf("failed to parse scan results to json, reason: %s", err.Error()) } return b, err } @@ -133,3 +127,19 @@ func envToString(env string, defaultValue string) string { } return defaultValue } + +func writeScanErrorToFile(err error, scanID string) error { + if e := os.MkdirAll(filepath.Dir(FailedOutputDir), os.ModePerm); e != nil { + return fmt.Errorf("failed to scan. reason: '%s'. failed to save error in file - failed to create directory. reason: %s", err.Error(), e.Error()) + } + f, e := os.Create(filepath.Join(FailedOutputDir, scanID)) + if e != nil { + return fmt.Errorf("failed to scan. reason: '%s'. failed to save error in file - failed to open file for writing. reason: %s", err.Error(), e.Error()) + } + defer f.Close() + + if _, e := f.Write([]byte(err.Error())); e != nil { + return fmt.Errorf("failed to scan. reason: '%s'. failed to save error in file - failed to write. reason: %s", err.Error(), e.Error()) + } + return fmt.Errorf("failed to scan. reason: '%s'", err.Error()) +}