Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func main() {
accessManagementWrapper := wrappers.NewAccessManagementHTTPWrapper(accessManagementPath)
byorWrapper := wrappers.NewByorHTTPWrapper(byorPath)
containerResolverWrapper := wrappers.NewContainerResolverWrapper()
enginesWrapper := wrappers.NewHttpEnginesWrapper()

astCli := commands.NewAstCLI(
applicationsWrapper,
Expand Down Expand Up @@ -127,6 +128,7 @@ func main() {
accessManagementWrapper,
byorWrapper,
containerResolverWrapper,
enginesWrapper,
)
exitListener()
err = astCli.Execute()
Expand Down
98 changes: 98 additions & 0 deletions internal/commands/engines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package commands

import (
"github.com/MakeNowJust/heredoc"
commonParams "github.com/checkmarx/ast-cli/internal/params"
"github.com/checkmarx/ast-cli/internal/wrappers"
"github.com/spf13/cobra"
)

type EngineAPIDetails struct {
EngineId string `format:"name:Engine ID"`
EngineName string `format:"name:Engine Name"`
ApiName string `format:"name:Api Name"`
ApiURL string `format:"name:Api URL"`
Description string `format:"name:Description"`
}

func NewEnginesCommand(
enginesWrapper wrappers.EnginesWrapper,
) *cobra.Command {
enginesCmd := &cobra.Command{
Use: "engines",
Short: "Manage engines",
Long: "The engines command enables the ability to manage engines in Checkmarx One.",
Annotations: map[string]string{
"command:doc": heredoc.Doc(
``,
),
},
}

getEngineListCmd := getEnginesListSubCommand(
enginesWrapper,
)
enginesCmd.AddCommand(
getEngineListCmd,
)
return enginesCmd
}

func getEnginesListSubCommand(
enginesWrapper wrappers.EnginesWrapper,
) *cobra.Command {
getEngineListCmd := &cobra.Command{
Use: "list-api",
Short: "Get list of all engines",
Long: "The list-api command is used to get list of all engine apis in Checkmarx One.",
Example: heredoc.Doc(
`
$ cx engines list-api --engine-name <Engine Name> --output-format <output-format>
`,
),
Annotations: map[string]string{
"command:doc": heredoc.Doc(
``,
),
},
RunE: runEngineGetListCommand(
enginesWrapper,
),
}
getEngineListCmd.PersistentFlags().String(commonParams.EngineName, "", "Filters Engines by EngineName")
getEngineListCmd.PersistentFlags().String(commonParams.OutputFormat, "table", "Show Engine Details based on Output Format")
return getEngineListCmd
}

func runEngineGetListCommand(
enginesWrapper wrappers.EnginesWrapper,
) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
var engineApiResponse *wrappers.EngineListResponseModel
engineName, _ := cmd.Flags().GetString(commonParams.EngineName)
engineApiResponse = enginesWrapper.Get(engineName)

if engineApiResponse != nil {
views := ShowEngineList(engineApiResponse.Engines)
return printByOutputFormat(cmd, views)
}
return nil
}
}

func ShowEngineList(engines []wrappers.EngineList) []*EngineAPIDetails {

views := make([]*EngineAPIDetails, 0)
for i := 0; i < len(engines); i++ {
for j := 0; j < len(engines[i].APIs); j++ {
views = append(views, &EngineAPIDetails{
EngineId: engines[i].EngineId,
EngineName: engines[i].EngineName,
ApiName: engines[i].APIs[j].ApiName,
ApiURL: engines[i].APIs[j].ApiURL,
Description: engines[i].APIs[j].Description,
})
}
}
return views
}
31 changes: 31 additions & 0 deletions internal/commands/engines_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build !integration

package commands

import (
"testing"
)

func TestEnginesHelp(t *testing.T) {
execCmdNilAssertion(t, "help", "engines")
}

func TestEnginesSub(t *testing.T) {
execCmdNilAssertion(t, "engines")
}

func TestGetAllEngineAPIs(t *testing.T) {
execCmdNilAssertion(t, "engines", "list-api")
}

func TestGetSASTEngineAPIs(t *testing.T) {
execCmdNilAssertion(t, "engines", "list-api", "--engine-name", "sast")
}

func TestGetSCAEngineAPIs(t *testing.T) {
execCmdNilAssertion(t, "engines", "list-api", "--engine-name", "sast")
}

func TestGetEngineAPIsWithNonExistFlag(t *testing.T) {
execCmdNilAssertion(t, "engines", "list-api", "--engine-name", "abc")
}
9 changes: 8 additions & 1 deletion internal/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func NewAstCLI(
accessManagementWrapper wrappers.AccessManagementWrapper,
byorWrapper wrappers.ByorWrapper,
containerResolverWrapper wrappers.ContainerResolverWrapper,
enginesWrapper wrappers.EnginesWrapper,
) *cobra.Command {
// Create the root
rootCmd := &cobra.Command{
Expand Down Expand Up @@ -202,7 +203,7 @@ func NewAstCLI(

chatCmd := NewChatCommand(chatWrapper, tenantWrapper)
hooksCmd := NewHooksCommand(jwtWrapper)

enginesCmd := NewEnginesCommand(enginesWrapper)
rootCmd.AddCommand(
scanCmd,
projectCmd,
Expand All @@ -214,6 +215,7 @@ func NewAstCLI(
configCmd,
chatCmd,
hooksCmd,
enginesCmd,
)

rootCmd.SilenceUsage = true
Expand Down Expand Up @@ -323,3 +325,8 @@ func printByScanInfoFormat(cmd *cobra.Command, view interface{}) error {
f, _ := cmd.Flags().GetString(params.ScanInfoFormatFlag)
return printer.Print(cmd.OutOrStdout(), view, f)
}

func printByOutputFormat(cmd *cobra.Command, view interface{}) error {
f, _ := cmd.Flags().GetString(params.OutputFormat)
return printer.Print(cmd.OutOrStdout(), view, f)
}
2 changes: 2 additions & 0 deletions internal/commands/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func createASTTestCommand() *cobra.Command {
byorWrapper := &mock.ByorMockWrapper{}
containerResolverMockWrapper := &mock.ContainerResolverMockWrapper{}
customStatesMockWrapper := &mock.CustomStatesMockWrapper{}
enginesWrapper := &wrappers.EngineHTTPWrapper{}
return NewAstCLI(
applicationWrapper,
scansMockWrapper,
Expand Down Expand Up @@ -103,6 +104,7 @@ func createASTTestCommand() *cobra.Command {
accessManagementWrapper,
byorWrapper,
containerResolverMockWrapper,
enginesWrapper,
)
}

Expand Down
2 changes: 2 additions & 0 deletions internal/params/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ const (
ContainersImageTagFilterFlag = "containers-image-tag-filter"
ContainersPackageFilterFlag = "containers-package-filter"
ContainersExcludeNonFinalStagesFlag = "containers-exclude-non-final-stages"
EngineName = "engine-name"
OutputFormat = "output-format"
)

// Parameter values
Expand Down
20 changes: 20 additions & 0 deletions internal/wrappers/engine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package wrappers

type EngineListResponseModel struct {
Engines []EngineList `json:"engines"`
}
type EngineList struct {
EngineId string `json:"engine_id"` // [git|upload]
EngineName string `json:"engine_name"` // One of [GitProjectHandler|ScanHandler]
APIs []EngineAPIs `json:"apis"`
}

type EngineAPIs struct {
ApiURL string `json:"api-url"` // [git|upload]
ApiName string `json:"api-name"` // One of [GitProjectHandler|ScanHandler]
Description string `json:"api-description"`
}

type EnginesWrapper interface {
Get(engineName string) *EngineListResponseModel
}
74 changes: 74 additions & 0 deletions internal/wrappers/engine_http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package wrappers

import (
"strings"
)

type EngineHTTPWrapper struct {
}

func (e *EngineHTTPWrapper) Get(engineName string) *EngineListResponseModel {
return e.getEngineList(engineName)
}

func NewHttpEnginesWrapper() *EngineHTTPWrapper {
return &EngineHTTPWrapper{}
}

func (e *EngineHTTPWrapper) getEngineList(engineName string) *EngineListResponseModel {
allEngines := &EngineListResponseModel{
Engines: []EngineList{
{
EngineId: "1",
EngineName: "SAST",
APIs: []EngineAPIs{
{
ApiURL: "https://{HostName}/api/v1/scans",
ApiName: "Get -> SAST Current Scans",
Description: "Gets List of current Scans",
},
{
ApiURL: "https://{HostName}/api/v1/scans/{id}/status",
ApiName: "Get -> SAST Scans status",
Description: "Retrieve that current status of Scan",
},
{
ApiURL: "https://{HostName}/api/v1/scans/{id}/results",
ApiName: "Get -> SAST Scans results",
Description: "Retrieve scan results",
},
},
},
{
EngineId: "2",
EngineName: "SCA",
APIs: []EngineAPIs{
{
ApiURL: "https://{HOST_NAME}/api/scans/{scanId}",
ApiName: "Get -> SCA scan details",
Description: "Retriever SCA scan details and status",
},
{
ApiURL: "https://{HOST_NAME}/api/scans",
ApiName: "Post -> Create a new SCA scan",
Description: "Create new scan and get the vulnerabilities in a packages",
},
},
},
},
}

if engineName != "" {
var filteredEngines []EngineList
for _, engine := range allEngines.Engines {
if strings.ToLower(engine.EngineName) == strings.ToLower(engineName) {
filteredEngines = append(filteredEngines, engine)
}
}

return &EngineListResponseModel{
Engines: filteredEngines,
}
}
return allEngines
}
71 changes: 71 additions & 0 deletions test/integration/engines_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//go:build integration

package integration

import (
"gotest.tools/assert"
"testing"
)

func TestGetAllEnginesApiList(t *testing.T) {
args := []string{
"engines", "list-api",
}

err, _ := executeCommand(t, args...)
assert.NilError(t, err)
}

func TestEnginesApiList_HelpSuccess(t *testing.T) {
args := []string{
"engines",
}

err, _ := executeCommand(t, args...)
assert.NilError(t, err)
}

func TestGetSASTEnginesApiList_Success(t *testing.T) {
args := []string{
"engines", "list-api", "--engine-name", "SAST",
}

err, _ := executeCommand(t, args...)
assert.NilError(t, err)
}

func TestGetSCAEnginesApiList_Success(t *testing.T) {
args := []string{
"engines", "list-api", "--engine-name", "SCA",
}

err, _ := executeCommand(t, args...)
assert.NilError(t, err)
}

func TestEnginesApiListInvalidFlagDetails_Error(t *testing.T) {
args := []string{
"engines", "list-api", "--engine-name", "xyz",
}

err, _ := executeCommand(t, args...)
assert.NilError(t, err)
}

func TestEnginesApiListInTableFormat_Success(t *testing.T) {
args := []string{
"engines", "list-api", "--output-format", "table", "--engine-name", "SAST",
}

err, _ := executeCommand(t, args...)
assert.NilError(t, err)
}

func TestEnginesApiListInJsonFormat_Success(t *testing.T) {
args := []string{
"engines", "list-api", "--output-format", "json", "--engine-name", "SAST",
}

err, _ := executeCommand(t, args...)
assert.NilError(t, err)
}
2 changes: 2 additions & 0 deletions test/integration/util_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ func createASTIntegrationTestCommand(t *testing.T) *cobra.Command {
accessManagementWrapper := wrappers.NewAccessManagementHTTPWrapper(accessManagementPath)
ByorWrapper := wrappers.NewByorHTTPWrapper(byorPath)
containerResolverWrapper := wrappers.NewContainerResolverWrapper()
enginesWrapper := wrappers.NewHttpEnginesWrapper()

astCli := commands.NewAstCLI(
applicationsWrapper,
Expand Down Expand Up @@ -159,6 +160,7 @@ func createASTIntegrationTestCommand(t *testing.T) *cobra.Command {
accessManagementWrapper,
ByorWrapper,
containerResolverWrapper,
enginesWrapper,
)
return astCli
}
Expand Down
Loading