From 71e3ec4b4abe28fc8d817168c89e14f9bebbe872 Mon Sep 17 00:00:00 2001 From: AlvoBen <144705560+AlvoBen@users.noreply.github.com> Date: Tue, 16 Jul 2024 14:49:28 +0300 Subject: [PATCH] CLI | Change Vorpal vorpal-latest-version flag flow (AST-48376) (#797) * change vorpal-latest-version flow * change vorpal-latest-version flow * resolve conversations * add bool type to osinstaller to improve readability * added unit tests * added unit tests * change the port configuration * fix unit tests --------- Co-authored-by: AlvoBen Co-authored-by: tamarleviCm --- internal/commands/scarealtime/sca-realtime.go | 2 +- internal/commands/vorpal/vorpal_test.go | 6 +- internal/services/osinstaller/os-installer.go | 16 ++--- internal/services/vorpal.go | 35 +++++------ internal/services/vorpal_test.go | 58 +++++++++++++++++++ 5 files changed, 89 insertions(+), 28 deletions(-) diff --git a/internal/commands/scarealtime/sca-realtime.go b/internal/commands/scarealtime/sca-realtime.go index 4451fbd4e..83e32b854 100644 --- a/internal/commands/scarealtime/sca-realtime.go +++ b/internal/commands/scarealtime/sca-realtime.go @@ -75,7 +75,7 @@ func RunScaRealtime(scaRealTimeWrapper wrappers.ScaRealTimeWrapper) func(*cobra. fmt.Println("Running SCA Realtime...") // Handle SCA Resolver. Checks if it already exists and if it is in the latest version - err = osinstaller.InstallOrUpgrade(&scaconfig.Params) + _, err = osinstaller.InstallOrUpgrade(&scaconfig.Params) if err != nil { return err } diff --git a/internal/commands/vorpal/vorpal_test.go b/internal/commands/vorpal/vorpal_test.go index 42a838b3e..dde020015 100644 --- a/internal/commands/vorpal/vorpal_test.go +++ b/internal/commands/vorpal/vorpal_test.go @@ -20,14 +20,14 @@ func TestInstallOrUpgrade_firstInstallation_Success(t *testing.T) { func firstInstallation() error { os.RemoveAll(vorpalconfig.Params.WorkingDir()) - err := osinstaller.InstallOrUpgrade(&vorpalconfig.Params) + _, err := osinstaller.InstallOrUpgrade(&vorpalconfig.Params) return err } func TestInstallOrUpgrade_installationIsUpToDate_Success(t *testing.T) { err := firstInstallation() assert.NilError(t, err, "Error on first installation of vorpal") - err = osinstaller.InstallOrUpgrade(&vorpalconfig.Params) + _, err = osinstaller.InstallOrUpgrade(&vorpalconfig.Params) assert.NilError(t, err, "Error when not need to upgrade") } @@ -35,7 +35,7 @@ func TestInstallOrUpgrade_installationIsNotUpToDate_Success(t *testing.T) { err := firstInstallation() assert.NilError(t, err, "Error on first installation of vorpal") changeHashFile() - err = osinstaller.InstallOrUpgrade(&vorpalconfig.Params) + _, err = osinstaller.InstallOrUpgrade(&vorpalconfig.Params) assert.NilError(t, err, "Error when need to upgrade") fileExists, _ := osinstaller.FileExists(vorpalconfig.Params.ExecutableFilePath()) assert.Assert(t, fileExists, "Executable file not found") diff --git a/internal/services/osinstaller/os-installer.go b/internal/services/osinstaller/os-installer.go index b508125c4..82994a457 100644 --- a/internal/services/osinstaller/os-installer.go +++ b/internal/services/osinstaller/os-installer.go @@ -15,6 +15,8 @@ import ( "github.com/pkg/errors" ) +type NewSuccessfulInstallation bool + // downloadFile Downloads a file from url path func downloadFile(downloadURLPath, filePath string) error { _, fileName := filepath.Split(filePath) @@ -50,38 +52,38 @@ func downloadFile(downloadURLPath, filePath string) error { // InstallOrUpgrade Checks the version according to the hash file, // downloads the RealTime installation if the version is not up-to-date, // Extracts the RealTime installation according to the operating system type -func InstallOrUpgrade(installationConfiguration *InstallationConfiguration) error { +func InstallOrUpgrade(installationConfiguration *InstallationConfiguration) (NewSuccessfulInstallation, error) { logger.PrintIfVerbose("Handling RealTime Installation...") if downloadNotNeeded(installationConfiguration) { logger.PrintIfVerbose("RealTime installation already exists and is up to date. Skipping download.") - return nil + return false, nil } // Create temporary working directory if not exists err := createWorkingDirectory(installationConfiguration) if err != nil { - return err + return false, err } // Download RealTime installation err = downloadFile(installationConfiguration.DownloadURL, filepath.Join(installationConfiguration.WorkingDir(), installationConfiguration.FileName)) if err != nil { - return err + return false, err } // Download hash file err = downloadHashFile(installationConfiguration.HashDownloadURL, installationConfiguration.HashFilePath()) if err != nil { - return err + return false, err } // Unzip or extract downloaded zip depending on which OS is running err = UnzipOrExtractFiles(installationConfiguration) if err != nil { - return err + return false, err } - return nil + return true, nil } // createWorkingDirectory Creates a working directory to handle Realtime functionality diff --git a/internal/services/vorpal.go b/internal/services/vorpal.go index 08a65eeab..cc84e9b65 100644 --- a/internal/services/vorpal.go +++ b/internal/services/vorpal.go @@ -37,19 +37,12 @@ type VorpalWrappersParam struct { } func CreateVorpalScanRequest(vorpalParams VorpalScanParams, wrapperParams VorpalWrappersParam) (*grpcs.ScanResult, error) { - var err error - wrapperParams.VorpalWrapper, err = configureVorpalWrapper(wrapperParams.VorpalWrapper) - vorpalWrapper := wrapperParams.VorpalWrapper + err := manageVorpalInstallation(vorpalParams, wrapperParams) if err != nil { return nil, err } - err = manageVorpalInstallation(vorpalParams, wrapperParams.VorpalWrapper) - if err != nil { - return nil, err - } - - err = ensureVorpalServiceRunning(wrapperParams, vorpalWrapper.GetPort(), vorpalParams) + err = ensureVorpalServiceRunning(wrapperParams, vorpalParams) if err != nil { return nil, err } @@ -93,16 +86,21 @@ func executeScan(vorpalWrapper grpcs.VorpalWrapper, filePath string) (*grpcs.Sca return vorpalWrapper.Scan(fileName, sourceCode) } -func manageVorpalInstallation(vorpalParams VorpalScanParams, vorpalWrapper grpcs.VorpalWrapper) error { +func manageVorpalInstallation(vorpalParams VorpalScanParams, vorpalWrappers VorpalWrappersParam) error { vorpalInstalled, _ := osinstaller.FileExists(vorpalconfig.Params.ExecutableFilePath()) - if vorpalParams.VorpalUpdateVersion || !vorpalInstalled { - if err := vorpalWrapper.HealthCheck(); err == nil { - _ = vorpalWrapper.ShutDown() + if !vorpalInstalled || vorpalParams.VorpalUpdateVersion { + if err := checkLicense(vorpalParams.IsDefaultAgent, vorpalWrappers); err != nil { + _ = vorpalWrappers.VorpalWrapper.ShutDown() + return err } - if err := osinstaller.InstallOrUpgrade(&vorpalconfig.Params); err != nil { + newInstallation, err := osinstaller.InstallOrUpgrade(&vorpalconfig.Params) + if err != nil { return err } + if newInstallation { + _ = vorpalWrappers.VorpalWrapper.ShutDown() + } } return nil } @@ -142,14 +140,17 @@ func setConfigPropertyQuiet(propName string, propValue int) { } } -func ensureVorpalServiceRunning(wrappersParam VorpalWrappersParam, port int, vorpalParams VorpalScanParams) error { +func ensureVorpalServiceRunning(wrappersParam VorpalWrappersParam, vorpalParams VorpalScanParams) error { if err := wrappersParam.VorpalWrapper.HealthCheck(); err != nil { err = checkLicense(vorpalParams.IsDefaultAgent, wrappersParam) if err != nil { return err } - - if err := RunVorpalEngine(port); err != nil { + wrappersParam.VorpalWrapper, err = configureVorpalWrapper(wrappersParam.VorpalWrapper) + if err != nil { + return err + } + if err := RunVorpalEngine(wrappersParam.VorpalWrapper.GetPort()); err != nil { return err } diff --git a/internal/services/vorpal_test.go b/internal/services/vorpal_test.go index 4d20f7d03..6300e7e3e 100644 --- a/internal/services/vorpal_test.go +++ b/internal/services/vorpal_test.go @@ -5,6 +5,7 @@ import ( "testing" errorconstants "github.com/checkmarx/ast-cli/internal/constants/errors" + "github.com/checkmarx/ast-cli/internal/wrappers/grpcs" "github.com/checkmarx/ast-cli/internal/wrappers/mock" "github.com/stretchr/testify/assert" ) @@ -66,3 +67,60 @@ func TestCreateVorpalScanRequest_SpecialAgentAndNoLicense_Fail(t *testing.T) { _, err := CreateVorpalScanRequest(vorpalParams, wrapperParams) assert.ErrorContains(t, err, errorconstants.NoVorpalLicense) } + +func TestCreateVorpalScanRequest_EngineRunningAndSpecialAgentAndNoLicense_Fail(t *testing.T) { + port, err := getAvailablePort() + if err != nil { + t.Fatalf("Failed to get available port: %v", err) + } + + vorpalParams := VorpalScanParams{ + FilePath: "data/python-vul-file.py", + VorpalUpdateVersion: true, + IsDefaultAgent: false, + } + + wrapperParams := VorpalWrappersParam{ + JwtWrapper: &mock.JWTMockWrapper{}, + FeatureFlagsWrapper: &mock.FeatureFlagsMockWrapper{}, + VorpalWrapper: grpcs.NewVorpalGrpcWrapper(port), + } + + err = ensureVorpalServiceRunning(wrapperParams, vorpalParams) + assert.Nil(t, err) + assert.Nil(t, wrapperParams.VorpalWrapper.HealthCheck()) + + wrapperParams.JwtWrapper = &mock.JWTMockWrapper{AIEnabled: mock.AIProtectionDisabled} + + err = manageVorpalInstallation(vorpalParams, wrapperParams) + assert.ErrorContains(t, err, errorconstants.NoVorpalLicense) + assert.NotNil(t, wrapperParams.VorpalWrapper.HealthCheck()) +} + +func TestCreateVorpalScanRequest_EngineRunningAndDefaultAgentAndNoLicense_Success(t *testing.T) { + port, err := getAvailablePort() + if err != nil { + t.Fatalf("Failed to get available port: %v", err) + } + + vorpalParams := VorpalScanParams{ + FilePath: "data/python-vul-file.py", + VorpalUpdateVersion: true, + IsDefaultAgent: true, + } + + wrapperParams := VorpalWrappersParam{ + JwtWrapper: &mock.JWTMockWrapper{AIEnabled: mock.AIProtectionDisabled}, + FeatureFlagsWrapper: &mock.FeatureFlagsMockWrapper{}, + VorpalWrapper: grpcs.NewVorpalGrpcWrapper(port), + } + + err = ensureVorpalServiceRunning(wrapperParams, vorpalParams) + assert.Nil(t, err) + assert.Nil(t, wrapperParams.VorpalWrapper.HealthCheck()) + + err = manageVorpalInstallation(vorpalParams, wrapperParams) + assert.Nil(t, err) + assert.Nil(t, wrapperParams.VorpalWrapper.HealthCheck()) + _ = wrapperParams.VorpalWrapper.ShutDown() +}