Skip to content

Commit

Permalink
Adding error logs report for audit scans (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
eranturgeman authored Apr 10, 2024
1 parent c9b84da commit 35f6200
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 9 deletions.
29 changes: 27 additions & 2 deletions cli/scancommands.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cli

import (
"fmt"
"github.com/jfrog/jfrog-cli-core/v2/utils/usage"
"os"
"strings"

Expand Down Expand Up @@ -328,7 +330,26 @@ func AuditCmd(c *components.Context) error {
}
}
auditCmd.SetTechnologies(technologies)
return progressbar.ExecWithProgress(auditCmd)
err = progressbar.ExecWithProgress(auditCmd)

// Reporting error if Xsc service is enabled
reportErrorIfExists(err, auditCmd)
return err
}

func reportErrorIfExists(err error, auditCmd *audit.AuditCommand) {
if err == nil || !usage.ShouldReportUsage() {
return
}
var serverDetails *coreConfig.ServerDetails
serverDetails, innerError := auditCmd.ServerDetails()
if innerError != nil {
log.Debug(fmt.Sprintf("failed to get server details for error report: %q", innerError))
return
}
if reportError := utils.ReportError(serverDetails, err, "cli"); reportError != nil {
log.Debug("failed to report error log:" + reportError.Error())
}
}

func createAuditCmd(c *components.Context) (*audit.AuditCommand, error) {
Expand Down Expand Up @@ -398,7 +419,11 @@ func AuditSpecificCmd(c *components.Context, technology coreutils.Technology) er
}
technologies := []string{string(technology)}
auditCmd.SetTechnologies(technologies)
return progressbar.ExecWithProgress(auditCmd)
err = progressbar.ExecWithProgress(auditCmd)

// Reporting error if Xsc service is enabled
reportErrorIfExists(err, auditCmd)
return err
}

func CurationCmd(c *components.Context) error {
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ require (
gopkg.in/warnings.v0 v0.1.2 // indirect
)

replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240404075604-3df49e9a9d64
replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240408074156-13680c04f22e

replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240403100335-8292671b7cc4
replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20240409191434-4e96d77edd64

// replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ github.com/jfrog/gofrog v1.6.3 h1:F7He0+75HcgCe6SGTSHLFCBDxiE2Ja0tekvvcktW6wc=
github.com/jfrog/gofrog v1.6.3/go.mod h1:SZ1EPJUruxrVGndOzHd+LTiwWYKMlHqhKD+eu+v5Hqg=
github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY=
github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w=
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240404075604-3df49e9a9d64 h1:eCAqJ8hqJ6bqgmjswjpqhInJMG80MT5D2r465s/fXzg=
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240404075604-3df49e9a9d64/go.mod h1:iQoYSsjLWF8x//rtQCwNPE2ycle2X2x6VFQM0LQE2n0=
github.com/jfrog/jfrog-client-go v1.28.1-0.20240403100335-8292671b7cc4 h1:A67yoFRYjRzg+xhLYhH0QN7b4/wggRa/lSQKSjzOwNQ=
github.com/jfrog/jfrog-client-go v1.28.1-0.20240403100335-8292671b7cc4/go.mod h1:tUyEmxznphh0nwAGo6xz9Sps7RRW/TBMxIJZteo+j2k=
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240408074156-13680c04f22e h1:PjCzGWHyJqK4j1MP3osPDDAW6KBXMJlBypOxKtp/ZKo=
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20240408074156-13680c04f22e/go.mod h1:qXAP68g+DlyX2wk5znNbQdK2CcEHfOLOfYXPzdlnkxI=
github.com/jfrog/jfrog-client-go v1.28.1-0.20240409191434-4e96d77edd64 h1:q0GV0IdhYdTqEkNykRwNZP0qNEE8j9dWfY9uKovDPzM=
github.com/jfrog/jfrog-client-go v1.28.1-0.20240409191434-4e96d77edd64/go.mod h1:tUyEmxznphh0nwAGo6xz9Sps7RRW/TBMxIJZteo+j2k=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
Expand Down
25 changes: 25 additions & 0 deletions utils/errorreport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package utils

import (
"fmt"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/jfrog/jfrog-client-go/xsc/services"
)

// Sends an error report when the Xsc service is enabled.
// Errors returned by this function typically do not disrupt the flow, as reporting errors is optional.
func ReportError(serverDetails *config.ServerDetails, errorToReport error, source string) error {
log.Debug("Sending an error report to JFrog analytics...")
xscManager, err := CreateXscServiceManager(serverDetails)
if err != nil {
return fmt.Errorf("failed to create an HTTP client: %s.\nReporting to JFrog analytics is skipped...", err.Error())
}

errorLog := &services.ExternalErrorLog{
Log_level: "error",
Source: source,
Message: errorToReport.Error(),
}
return SendXscLogMessageIfEnabled(errorLog, xscManager)
}
69 changes: 69 additions & 0 deletions utils/errorreport_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package utils

import (
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
clienttestutils "github.com/jfrog/jfrog-client-go/utils/tests"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)

const (
unsupportedXscVersionForErrorLogs = "1.6.0"
supportedXscVersionForErrorLogs = minXscVersionForErrorReport
)

func TestReportLogErrorEventPossible(t *testing.T) {
restoreEnvVarFunc := clienttestutils.SetEnvWithCallbackAndAssert(t, coreutils.ReportUsage, "")
defer restoreEnvVarFunc()

testCases := []struct {
serverCreationFunc func() (*httptest.Server, *config.ServerDetails)
expectedResponse bool
}{
{
serverCreationFunc: func() (*httptest.Server, *config.ServerDetails) {
serverMock, serverDetails, _ := CreateXscRestsMockServer(t, func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "/xsc/api/v1/system/version" {
w.WriteHeader(http.StatusNotFound)
_, innerError := w.Write([]byte("Xsc service is not enabled"))
if innerError != nil {
return
}
}
})
return serverMock, serverDetails
},
expectedResponse: false,
},
{
serverCreationFunc: func() (*httptest.Server, *config.ServerDetails) { return xscServer(t, "") },
expectedResponse: false,
},
{
serverCreationFunc: func() (*httptest.Server, *config.ServerDetails) {
return xscServer(t, unsupportedXscVersionForErrorLogs)
},
expectedResponse: false,
},
{
serverCreationFunc: func() (*httptest.Server, *config.ServerDetails) { return xscServer(t, supportedXscVersionForErrorLogs) },
expectedResponse: true,
},
}

for _, testcase := range testCases {
mockServer, serverDetails := testcase.serverCreationFunc()
xscManager, err := CreateXscServiceManager(serverDetails)
assert.NoError(t, err)
reportPossible := IsReportLogErrorEventPossible(xscManager)
if testcase.expectedResponse {
assert.True(t, reportPossible)
} else {
assert.False(t, reportPossible)
}
mockServer.Close()
}
}
34 changes: 33 additions & 1 deletion utils/xscmanager.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package utils

import (
"fmt"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
clientconfig "github.com/jfrog/jfrog-client-go/config"
clientutils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/log"
"github.com/jfrog/jfrog-client-go/xsc"
"github.com/jfrog/jfrog-client-go/xsc/services"

clientconfig "github.com/jfrog/jfrog-client-go/config"
)

const minXscVersionForErrorReport = "1.7.7"

func CreateXscServiceManager(serviceDetails *config.ServerDetails) (*xsc.XscServicesManager, error) {
xscDetails, err := serviceDetails.CreateXscAuthConfig()
if err != nil {
Expand All @@ -19,3 +26,28 @@ func CreateXscServiceManager(serviceDetails *config.ServerDetails) (*xsc.XscServ
}
return xsc.New(serviceConfig)
}

func SendXscLogMessageIfEnabled(errorLog *services.ExternalErrorLog, xscManager *xsc.XscServicesManager) error {
if !IsReportLogErrorEventPossible(xscManager) {
return nil
}
return xscManager.SendXscLogErrorRequest(errorLog)
}

// Determines if reporting the error is feasible.
func IsReportLogErrorEventPossible(xscManager *xsc.XscServicesManager) bool {
xscVersion, err := xscManager.GetVersion()
if err != nil {
log.Debug(fmt.Sprintf("failed to check availability of Xsc service:%s\nReporting to JFrog analytics is skipped...", err.Error()))
return false
}
if xscVersion == "" {
log.Debug("Xsc service is not available. Reporting to JFrog analytics is skipped...")
return false
}
if err = clientutils.ValidateMinimumVersion(clientutils.Xsc, xscVersion, minXscVersionForErrorReport); err != nil {
log.Debug(err.Error())
return false
}
return true
}
31 changes: 31 additions & 0 deletions xsc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"errors"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-security/tests"
"github.com/jfrog/jfrog-cli-security/utils"
"github.com/stretchr/testify/assert"
"testing"
)

func TestReportError(t *testing.T) {
serverDetails := &config.ServerDetails{
Url: *tests.JfrogUrl,
ArtifactoryUrl: *tests.JfrogUrl + tests.ArtifactoryEndpoint,
XrayUrl: *tests.JfrogUrl + tests.XrayEndpoint,
AccessToken: *tests.JfrogAccessToken,
ServerId: tests.ServerId,
}

// Prior to initiating the test, we verify whether Xsc is enabled for the customer. If not, the test is skipped.
xscManager, err := utils.CreateXscServiceManager(serverDetails)
assert.NoError(t, err)

if !utils.IsReportLogErrorEventPossible(xscManager) {
t.Skip("Skipping test since Xsc server is not enabled or below minimal required version")
}

errorToReport := errors.New("THIS IS NOT A REAL ERROR! This Error is posted as part of TestReportError test")
assert.NoError(t, utils.ReportError(serverDetails, errorToReport, "cli"))
}

0 comments on commit 35f6200

Please sign in to comment.