Skip to content

Commit cd22348

Browse files
Added new command engines list-api which returns list of engine APIs
1 parent 8541016 commit cd22348

11 files changed

Lines changed: 312 additions & 1 deletion

File tree

cmd/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func main() {
9191
accessManagementWrapper := wrappers.NewAccessManagementHTTPWrapper(accessManagementPath)
9292
byorWrapper := wrappers.NewByorHTTPWrapper(byorPath)
9393
containerResolverWrapper := wrappers.NewContainerResolverWrapper()
94+
enginesWrapper := wrappers.NewHttpEnginesWrapper()
9495

9596
astCli := commands.NewAstCLI(
9697
applicationsWrapper,
@@ -127,6 +128,7 @@ func main() {
127128
accessManagementWrapper,
128129
byorWrapper,
129130
containerResolverWrapper,
131+
enginesWrapper,
130132
)
131133
exitListener()
132134
err = astCli.Execute()

internal/commands/engines.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package commands
2+
3+
import (
4+
"github.com/MakeNowJust/heredoc"
5+
commonParams "github.com/checkmarx/ast-cli/internal/params"
6+
"github.com/checkmarx/ast-cli/internal/wrappers"
7+
"github.com/spf13/cobra"
8+
)
9+
10+
type EngineAPIDetails struct {
11+
EngineId string `format:"name:Engine ID"`
12+
EngineName string `format:"name:Engine Name"`
13+
ApiName string `format:"name:Api Name"`
14+
ApiURL string `format:"name:Api URL"`
15+
Description string `format:"name:Description"`
16+
}
17+
18+
func NewEnginesCommand(
19+
enginesWrapper wrappers.EnginesWrapper,
20+
) *cobra.Command {
21+
enginesCmd := &cobra.Command{
22+
Use: "engines",
23+
Short: "Manage engines",
24+
Long: "The engines command enables the ability to manage engines in Checkmarx One.",
25+
Annotations: map[string]string{
26+
"command:doc": heredoc.Doc(
27+
``,
28+
),
29+
},
30+
}
31+
32+
getEngineListCmd := getEnginesListSubCommand(
33+
enginesWrapper,
34+
)
35+
enginesCmd.AddCommand(
36+
getEngineListCmd,
37+
)
38+
return enginesCmd
39+
}
40+
41+
func getEnginesListSubCommand(
42+
enginesWrapper wrappers.EnginesWrapper,
43+
) *cobra.Command {
44+
getEngineListCmd := &cobra.Command{
45+
Use: "list-api",
46+
Short: "Get list of all engines",
47+
Long: "The list-api command is used to get list of all engine apis in Checkmarx One.",
48+
Example: heredoc.Doc(
49+
`
50+
$ cx engines list-api --engine-name <Engine Name> --output-format <output-format>
51+
`,
52+
),
53+
Annotations: map[string]string{
54+
"command:doc": heredoc.Doc(
55+
``,
56+
),
57+
},
58+
RunE: runEngineGetListCommand(
59+
enginesWrapper,
60+
),
61+
}
62+
getEngineListCmd.PersistentFlags().String(commonParams.EngineName, "", "Filters Engines by EngineName")
63+
getEngineListCmd.PersistentFlags().String(commonParams.OutputFormat, "table", "Show Engine Details based on Output Format")
64+
return getEngineListCmd
65+
}
66+
67+
func runEngineGetListCommand(
68+
enginesWrapper wrappers.EnginesWrapper,
69+
) func(cmd *cobra.Command, args []string) error {
70+
return func(cmd *cobra.Command, args []string) error {
71+
var engineApiResponse *wrappers.EngineListResponseModel
72+
engineName, _ := cmd.Flags().GetString(commonParams.EngineName)
73+
engineApiResponse = enginesWrapper.Get(engineName)
74+
75+
if engineApiResponse != nil {
76+
views := ShowEngineList(engineApiResponse.Engines)
77+
return printByOutputFormat(cmd, views)
78+
}
79+
return nil
80+
}
81+
}
82+
83+
func ShowEngineList(engines []wrappers.EngineList) []*EngineAPIDetails {
84+
85+
views := make([]*EngineAPIDetails, 0)
86+
for i := 0; i < len(engines); i++ {
87+
for j := 0; j < len(engines[i].APIs); j++ {
88+
views = append(views, &EngineAPIDetails{
89+
EngineId: engines[i].EngineId,
90+
EngineName: engines[i].EngineName,
91+
ApiName: engines[i].APIs[j].ApiName,
92+
ApiURL: engines[i].APIs[j].ApiURL,
93+
Description: engines[i].APIs[j].Description,
94+
})
95+
}
96+
}
97+
return views
98+
}

internal/commands/engines_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//go:build !integration
2+
3+
package commands
4+
5+
import (
6+
"testing"
7+
)
8+
9+
func TestEnginesHelp(t *testing.T) {
10+
execCmdNilAssertion(t, "help", "engines")
11+
}
12+
13+
func TestEnginesSub(t *testing.T) {
14+
execCmdNilAssertion(t, "engines")
15+
}
16+
17+
func TestGetAllEngineAPIs(t *testing.T) {
18+
execCmdNilAssertion(t, "engines", "list-api")
19+
}
20+
21+
func TestGetSASTEngineAPIs(t *testing.T) {
22+
execCmdNilAssertion(t, "engines", "list-api", "--engine-name", "sast")
23+
}
24+
25+
func TestGetSCAEngineAPIs(t *testing.T) {
26+
execCmdNilAssertion(t, "engines", "list-api", "--engine-name", "sast")
27+
}
28+
29+
func TestGetEngineAPIsWithNonExistFlag(t *testing.T) {
30+
execCmdNilAssertion(t, "engines", "list-api", "--engine-name", "abc")
31+
}

internal/commands/root.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func NewAstCLI(
5555
accessManagementWrapper wrappers.AccessManagementWrapper,
5656
byorWrapper wrappers.ByorWrapper,
5757
containerResolverWrapper wrappers.ContainerResolverWrapper,
58+
enginesWrapper wrappers.EnginesWrapper,
5859
) *cobra.Command {
5960
// Create the root
6061
rootCmd := &cobra.Command{
@@ -195,14 +196,15 @@ func NewAstCLI(
195196
applicationsWrapper,
196197
byorWrapper,
197198
featureFlagsWrapper,
199+
enginesWrapper,
198200
)
199201

200202
configCmd := util.NewConfigCommand()
201203
triageCmd := NewResultsPredicatesCommand(resultsPredicatesWrapper, featureFlagsWrapper, customStatesWrapper)
202204

203205
chatCmd := NewChatCommand(chatWrapper, tenantWrapper)
204206
hooksCmd := NewHooksCommand(jwtWrapper)
205-
207+
enginesCmd := NewEnginesCommand(enginesWrapper)
206208
rootCmd.AddCommand(
207209
scanCmd,
208210
projectCmd,
@@ -214,6 +216,7 @@ func NewAstCLI(
214216
configCmd,
215217
chatCmd,
216218
hooksCmd,
219+
enginesCmd,
217220
)
218221

219222
rootCmd.SilenceUsage = true
@@ -323,3 +326,8 @@ func printByScanInfoFormat(cmd *cobra.Command, view interface{}) error {
323326
f, _ := cmd.Flags().GetString(params.ScanInfoFormatFlag)
324327
return printer.Print(cmd.OutOrStdout(), view, f)
325328
}
329+
330+
func printByOutputFormat(cmd *cobra.Command, view interface{}) error {
331+
f, _ := cmd.Flags().GetString(params.OutputFormat)
332+
return printer.Print(cmd.OutOrStdout(), view, f)
333+
}

internal/commands/root_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func createASTTestCommand() *cobra.Command {
6868
byorWrapper := &mock.ByorMockWrapper{}
6969
containerResolverMockWrapper := &mock.ContainerResolverMockWrapper{}
7070
customStatesMockWrapper := &mock.CustomStatesMockWrapper{}
71+
enginesWrapper := &wrappers.EngineHTTPWrapper{}
7172
return NewAstCLI(
7273
applicationWrapper,
7374
scansMockWrapper,
@@ -103,6 +104,7 @@ func createASTTestCommand() *cobra.Command {
103104
accessManagementWrapper,
104105
byorWrapper,
105106
containerResolverMockWrapper,
107+
enginesWrapper,
106108
)
107109
}
108110

internal/commands/util/utils.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func NewUtilsCommand(
4545
applicationsWrapper wrappers.ApplicationsWrapper,
4646
byorWrapper wrappers.ByorWrapper,
4747
featureFlagsWrapper wrappers.FeatureFlagsWrapper,
48+
enginesWrapper wrappers.EnginesWrapper,
4849
) *cobra.Command {
4950
utilsCmd := &cobra.Command{
5051
Use: "utils",

internal/params/flags.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ const (
217217
ContainersImageTagFilterFlag = "containers-image-tag-filter"
218218
ContainersPackageFilterFlag = "containers-package-filter"
219219
ContainersExcludeNonFinalStagesFlag = "containers-exclude-non-final-stages"
220+
EngineName = "engine-name"
221+
OutputFormat = "output-format"
220222
)
221223

222224
// Parameter values

internal/wrappers/engine.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package wrappers
2+
3+
type EngineListResponseModel struct {
4+
Engines []EngineList `json:"engines"`
5+
}
6+
type EngineList struct {
7+
EngineId string `json:"engine_id"` // [git|upload]
8+
EngineName string `json:"engine_name"` // One of [GitProjectHandler|ScanHandler]
9+
APIs []EngineAPIs `json:"apis"`
10+
}
11+
12+
type EngineAPIs struct {
13+
ApiURL string `json:"api-url"` // [git|upload]
14+
ApiName string `json:"api-name"` // One of [GitProjectHandler|ScanHandler]
15+
Description string `json:"api-description"`
16+
}
17+
18+
type EnginesWrapper interface {
19+
Get(engineName string) *EngineListResponseModel
20+
}

internal/wrappers/engine_http.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package wrappers
2+
3+
import (
4+
"strings"
5+
)
6+
7+
type EngineHTTPWrapper struct {
8+
}
9+
10+
func (e *EngineHTTPWrapper) Get(engineName string) *EngineListResponseModel {
11+
return e.getEngineList(engineName)
12+
}
13+
14+
func NewHttpEnginesWrapper() *EngineHTTPWrapper {
15+
return &EngineHTTPWrapper{}
16+
}
17+
18+
func (e *EngineHTTPWrapper) getEngineList(engineName string) *EngineListResponseModel {
19+
allEngines := &EngineListResponseModel{
20+
Engines: []EngineList{
21+
{
22+
EngineId: "1",
23+
EngineName: "SAST",
24+
APIs: []EngineAPIs{
25+
{
26+
ApiURL: "https://{HostName}/api/v1/scans",
27+
ApiName: "Get -> SAST Current Scans",
28+
Description: "Gets List of current Scans",
29+
},
30+
{
31+
ApiURL: "https://{HostName}/api/v1/scans/{id}/status",
32+
ApiName: "Get -> SAST Scans status",
33+
Description: "Retrieve that current status of Scan",
34+
},
35+
{
36+
ApiURL: "https://{HostName}/api/v1/scans/{id}/results",
37+
ApiName: "Get -> SAST Scans results",
38+
Description: "Retrieve scan results",
39+
},
40+
},
41+
},
42+
{
43+
EngineId: "2",
44+
EngineName: "SCA",
45+
APIs: []EngineAPIs{
46+
{
47+
ApiURL: "https://{HOST_NAME}/api/scans/{scanId}",
48+
ApiName: "Get -> SCA scan details",
49+
Description: "Retriever SCA scan details and status",
50+
},
51+
{
52+
ApiURL: "https://{HOST_NAME}/api/scans",
53+
ApiName: "Post -> Create a new SCA scan",
54+
Description: "Create new scan and get the vulnerabilities in a packages",
55+
},
56+
},
57+
},
58+
},
59+
}
60+
61+
if engineName != "" {
62+
var filteredEngines []EngineList
63+
for _, engine := range allEngines.Engines {
64+
if strings.ToLower(engine.EngineName) == strings.ToLower(engineName) {
65+
filteredEngines = append(filteredEngines, engine)
66+
}
67+
}
68+
69+
return &EngineListResponseModel{
70+
Engines: filteredEngines,
71+
}
72+
}
73+
return allEngines
74+
}

test/integration/engines_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//go:build integration
2+
3+
package integration
4+
5+
import (
6+
"gotest.tools/assert"
7+
"testing"
8+
)
9+
10+
func TestGetAllEnginesApiList(t *testing.T) {
11+
args := []string{
12+
"engines", "list-api",
13+
}
14+
15+
err, _ := executeCommand(t, args...)
16+
assert.NilError(t, err)
17+
}
18+
19+
func TestEnginesApiList_HelpSuccess(t *testing.T) {
20+
args := []string{
21+
"engines",
22+
}
23+
24+
err, _ := executeCommand(t, args...)
25+
assert.NilError(t, err)
26+
}
27+
28+
func TestGetSASTEnginesApiList_Success(t *testing.T) {
29+
args := []string{
30+
"engines", "list-api", "--engine-name", "SAST",
31+
}
32+
33+
err, _ := executeCommand(t, args...)
34+
assert.NilError(t, err)
35+
}
36+
37+
func TestGetSCAEnginesApiList_Success(t *testing.T) {
38+
args := []string{
39+
"engines", "list-api", "--engine-name", "SCA",
40+
}
41+
42+
err, _ := executeCommand(t, args...)
43+
assert.NilError(t, err)
44+
}
45+
46+
func TestEnginesApiListInvalidFlagDetails_Error(t *testing.T) {
47+
args := []string{
48+
"engines", "list-api", "--engine-name", "xyz",
49+
}
50+
51+
err, _ := executeCommand(t, args...)
52+
assert.NilError(t, err)
53+
}
54+
55+
func TestEnginesApiListInTableFormat_Success(t *testing.T) {
56+
args := []string{
57+
"engines", "list-api", "--output-format", "table", "--engine-name", "SAST",
58+
}
59+
60+
err, _ := executeCommand(t, args...)
61+
assert.NilError(t, err)
62+
}
63+
64+
func TestEnginesApiListInJsonFormat_Success(t *testing.T) {
65+
args := []string{
66+
"engines", "list-api", "--output-format", "json", "--engine-name", "SAST",
67+
}
68+
69+
err, _ := executeCommand(t, args...)
70+
assert.NilError(t, err)
71+
}

0 commit comments

Comments
 (0)