Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5d957d9
start adding code and test
cx-ronit-steinberg Jan 12, 2026
c717b9c
add to test
cx-ronit-steinberg Jan 12, 2026
07fe229
improve test
cx-ronit-steinberg Jan 12, 2026
d73c7bb
fix
cx-ronit-steinberg Jan 12, 2026
07c3e13
fix
cx-ronit-steinberg Jan 12, 2026
e1098db
Merge branch 'main' into AST-129589-dast-enabled
cx-ronit-steinberg Jan 12, 2026
b1d0c5f
use assert instead of require
cx-ronit-steinberg Jan 12, 2026
f8e4c08
use tenant command
cx-ronit-steinberg Jan 13, 2026
698a9f5
remove command
cx-ronit-steinberg Jan 13, 2026
63882fa
add test
cx-ronit-steinberg Jan 13, 2026
d3f3c33
fix test
cx-ronit-steinberg Jan 13, 2026
ee6af7d
undo change
cx-ronit-steinberg Jan 13, 2026
7e638ff
undo changes
cx-ronit-steinberg Jan 13, 2026
d1058d2
undo
cx-ronit-steinberg Jan 13, 2026
c7cfcb4
lint
cx-ronit-steinberg Jan 13, 2026
8a4831c
lint
cx-ronit-steinberg Jan 13, 2026
4dc61d5
start adding environments command
cx-ronit-steinberg Jan 13, 2026
76ebb37
filters and test
cx-ronit-steinberg Jan 13, 2026
2c87f20
Merge branch 'main' into feature/AST-129883-environments-api
cx-ronit-steinberg Jan 14, 2026
b66c948
lint
cx-ronit-steinberg Jan 14, 2026
926b095
lint
cx-ronit-steinberg Jan 14, 2026
d451fb3
fix
cx-ronit-steinberg Jan 14, 2026
323a78c
fix
cx-ronit-steinberg Jan 14, 2026
47e53b3
move commands to commandutils
cx-ronit-steinberg Jan 15, 2026
61fd3b2
use simpler GetFilters function
cx-ronit-steinberg Jan 15, 2026
8d431ea
rename environment to dast-environment
cx-ronit-steinberg Jan 15, 2026
e3b3e48
move tests to package
cx-ronit-steinberg Jan 15, 2026
ebe7323
rename
cx-ronit-steinberg Jan 15, 2026
ca414a9
rename
cx-ronit-steinberg Jan 15, 2026
5b8d645
lint
cx-ronit-steinberg Jan 15, 2026
252b50c
Merge branch 'main' into feature/AST-129883-environments-api
cx-ronit-steinberg Jan 15, 2026
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
3 changes: 3 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func main() {
accessManagementPath := viper.GetString(params.AccessManagementPathKey)
byorPath := viper.GetString(params.ByorPathKey)
realtimeScannerPath := viper.GetString(params.RealtimeScannerPathKey)
dastEnvironmentsPath := viper.GetString(params.DastEnvironmentsPathKey)

customStatesWrapper := wrappers.NewCustomStatesHTTPWrapper()
scansWrapper := wrappers.NewHTTPScansWrapper(scans)
Expand Down Expand Up @@ -97,6 +98,7 @@ func main() {
containerResolverWrapper := wrappers.NewContainerResolverWrapper()
realTimeWrapper := wrappers.NewRealtimeScannerHTTPWrapper(realtimeScannerPath, jwtWrapper, featureFlagsWrapper)
telemetryWrapper := wrappers.NewHTTPTelemetryAIWrapper(realtimeScannerPath)
dastEnvironmentsWrapper := wrappers.NewHTTPDastEnvironmentsWrapper(dastEnvironmentsPath)

astCli := commands.NewAstCLI(
applicationsWrapper,
Expand Down Expand Up @@ -136,6 +138,7 @@ func main() {
containerResolverWrapper,
realTimeWrapper,
telemetryWrapper,
dastEnvironmentsWrapper,
)
exitListener()
err = astCli.Execute()
Expand Down
45 changes: 45 additions & 0 deletions internal/commands/commandutils/commandutils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package commandutils

import (
"errors"
"fmt"
"strings"

"github.com/checkmarx/ast-cli/internal/commands/util/printer"
"github.com/checkmarx/ast-cli/internal/params"
"github.com/spf13/cobra"
)

func AddFormatFlagToMultipleCommands(commands []*cobra.Command, defaultFormat string, otherAvailableFormats ...string) {
for _, c := range commands {
AddFormatFlag(c, defaultFormat, otherAvailableFormats...)
}
}

func AddFormatFlag(cmd *cobra.Command, defaultFormat string, otherAvailableFormats ...string) {
cmd.PersistentFlags().String(
params.FormatFlag, defaultFormat,
fmt.Sprintf(params.FormatFlagUsageFormat, append(otherAvailableFormats, defaultFormat)),
)
}

func PrintByFormat(cmd *cobra.Command, view interface{}) error {
f, _ := cmd.Flags().GetString(params.FormatFlag)
return printer.Print(cmd.OutOrStdout(), view, f)
}

func GetFilters(cmd *cobra.Command) (map[string]string, error) {
filters, _ := cmd.Flags().GetStringSlice(params.FilterFlag)
allFilters := make(map[string]string)
for _, filter := range filters {
filterKeyVal := strings.Split(filter, "=")
if len(filterKeyVal) != params.KeyValuePairSize {
return nil, errors.New("invalid filters, filters should be in a KEY=VALUE format")
}
allFilters[filterKeyVal[0]] = strings.Replace(
filterKeyVal[1], ";", ",",
strings.Count(filterKeyVal[1], ";"),
)
}
return allFilters, nil
}
142 changes: 142 additions & 0 deletions internal/commands/dast/dast-environments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package dast

import (
"fmt"
"strings"

"github.com/MakeNowJust/heredoc"
"github.com/checkmarx/ast-cli/internal/commands/commandutils"
"github.com/checkmarx/ast-cli/internal/commands/util/printer"
commonParams "github.com/checkmarx/ast-cli/internal/params"
"github.com/checkmarx/ast-cli/internal/services"
"github.com/checkmarx/ast-cli/internal/wrappers"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

const (
failedGettingDastEnvironments = "Failed getting DAST environments"
)

var (
filterDastEnvironmentsListFlagUsage = fmt.Sprintf(
"Filter the list of DAST environments. Use ';' as the delimiter for arrays. Available filters are: %s",
strings.Join(
[]string{
commonParams.FromQueryParam,
commonParams.ToQueryParam,
commonParams.SearchQueryParam,
commonParams.SortQueryParam,
}, ",",
),
)
)

// NewDastEnvironmentsCommand creates the DAST environments command
func NewDastEnvironmentsCommand(dastEnvironmentsWrapper wrappers.DastEnvironmentsWrapper) *cobra.Command {
environmentsCmd := &cobra.Command{
Use: "dast-environments",
Short: "Manage DAST environments",
Long: "The environments command enables the ability to manage DAST environments in Checkmarx One",
Annotations: map[string]string{
"command:doc": heredoc.Doc(
`
https://checkmarx.com/resource/documents/en/todo
`,
),
},
}

listDastEnvironmentsCmd := &cobra.Command{
Use: "list",
Short: "List all DAST environments in the system",
Example: heredoc.Doc(
`
$ cx dast-environments list --format list
$ cx dast-environments list --filter "from=1,to=10"
$ cx dast-environments list --filter "search=production,sort=created"
`,
),
Annotations: map[string]string{
"command:doc": heredoc.Doc(
`
https://checkmarx.com/resource/documents/en/todo
`,
),
},
RunE: runListDastEnvironmentsCommand(dastEnvironmentsWrapper),
}
listDastEnvironmentsCmd.PersistentFlags().StringSlice(commonParams.FilterFlag, []string{}, filterDastEnvironmentsListFlagUsage)

commandutils.AddFormatFlagToMultipleCommands(
[]*cobra.Command{listDastEnvironmentsCmd},
printer.FormatTable,
printer.FormatJSON,
printer.FormatList,
)

environmentsCmd.AddCommand(listDastEnvironmentsCmd)
return environmentsCmd
}

func runListDastEnvironmentsCommand(dastEnvironmentsWrapper wrappers.DastEnvironmentsWrapper) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
var allEnvironmentsModel *wrappers.DastEnvironmentsCollectionResponseModel
var errorModel *wrappers.ErrorModel

params, err := commandutils.GetFilters(cmd)
if err != nil {
return errors.Wrapf(err, "%s", failedGettingDastEnvironments)
}

// The API expects: from, to, search, sort
// from and to are pagination parameters (e.g., from=1, to=10 for first page)
allEnvironmentsModel, errorModel, err = dastEnvironmentsWrapper.Get(params)
if err != nil {
return errors.Wrapf(err, "%s\n", failedGettingDastEnvironments)
}

// Checking the response
if errorModel != nil {
return errors.Errorf(services.ErrorCodeFormat, failedGettingDastEnvironments, errorModel.Code, errorModel.Message)
} else if allEnvironmentsModel != nil && allEnvironmentsModel.Environments != nil {
err = commandutils.PrintByFormat(cmd, toEnvironmentViews(allEnvironmentsModel.Environments))
if err != nil {
return err
}
}
return nil
}
}

func toEnvironmentViews(models []wrappers.DastEnvironmentResponseModel) []environmentView {
result := make([]environmentView, len(models))
for i := 0; i < len(models); i++ {
result[i] = toEnvironmentView(&models[i])
}
return result
}

func toEnvironmentView(model *wrappers.DastEnvironmentResponseModel) environmentView {
return environmentView{
EnvironmentID: model.EnvironmentID,
Domain: model.Domain,
URL: model.URL,
ScanType: model.ScanType,
Created: model.Created,
RiskRating: model.RiskRating,
LastScanTime: model.LastScanTime,
LastStatus: model.LastStatus,
}
}

type environmentView struct {
EnvironmentID string `format:"name:Environment ID"`
Domain string
URL string
ScanType string `format:"name:Scan Type"`
Created string
RiskRating string `format:"name:Risk Rating"`
LastScanTime string `format:"name:Last Scan Time"`
LastStatus string `format:"name:Last Status"`
}
51 changes: 51 additions & 0 deletions internal/commands/dast/dast-environments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//go:build !integration

package dast

import (
"testing"

"github.com/checkmarx/ast-cli/internal/wrappers/mock"
"gotest.tools/assert"
)

func createTestCommand(args ...string) error {
cmd := NewDastEnvironmentsCommand(&mock.DastEnvironmentsMockWrapper{})
cmd.SetArgs(args)
return cmd.Execute()
}

func TestDastEnvironmentsHelp(t *testing.T) {
err := createTestCommand("--help")
assert.NilError(t, err)
}

func TestDastEnvironmentsNoSub(t *testing.T) {
err := createTestCommand()
assert.NilError(t, err)
}

func TestDastEnvironmentsList(t *testing.T) {
err := createTestCommand("list")
assert.NilError(t, err)
}

func TestDastEnvironmentsListWithFormat(t *testing.T) {
err := createTestCommand("list", "--format", "json")
assert.NilError(t, err)
}

func TestDastEnvironmentsListWithFilters(t *testing.T) {
err := createTestCommand("list", "--filter", "from=1,to=10")
assert.NilError(t, err)
}

func TestDastEnvironmentsListWithSearch(t *testing.T) {
err := createTestCommand("list", "--filter", "search=test")
assert.NilError(t, err)
}

func TestDastEnvironmentsListWithSort(t *testing.T) {
err := createTestCommand("list", "--filter", "sort=domain:asc")
assert.NilError(t, err)
}
7 changes: 4 additions & 3 deletions internal/commands/predicates.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"encoding/json"

"github.com/MakeNowJust/heredoc"
"github.com/checkmarx/ast-cli/internal/commands/commandutils"
"github.com/checkmarx/ast-cli/internal/commands/util/printer"
"github.com/checkmarx/ast-cli/internal/logger"
"github.com/checkmarx/ast-cli/internal/params"
Expand All @@ -35,7 +36,7 @@ func NewResultsPredicatesCommand(resultsPredicatesWrapper wrappers.ResultsPredic
triageUpdateCmd := triageUpdateSubCommand(resultsPredicatesWrapper, featureFlagsWrapper, customStatesWrapper)
triageGetStatesCmd := triageGetStatesSubCommand(customStatesWrapper, featureFlagsWrapper)

addFormatFlagToMultipleCommands(
commandutils.AddFormatFlagToMultipleCommands(
[]*cobra.Command{triageShowCmd},
printer.FormatList, printer.FormatTable, printer.FormatJSON,
)
Expand Down Expand Up @@ -184,7 +185,7 @@ func runTriageShow(resultsPredicatesWrapper wrappers.ResultsPredicatesWrapper) f
if err != nil {
return errors.Wrapf(err, "%s", "Failed showing the predicate")
}
err = printByFormat(cmd, toScaPredicateResultView(scaPredicates))
err = commandutils.PrintByFormat(cmd, toScaPredicateResultView(scaPredicates))
if err != nil {
return err
}
Expand All @@ -203,7 +204,7 @@ func runTriageShow(resultsPredicatesWrapper wrappers.ResultsPredicatesWrapper) f
errorModel.Message,
)
} else if predicatesCollection != nil {
err = printByFormat(cmd, toPredicatesView(*predicatesCollection))
err = commandutils.PrintByFormat(cmd, toPredicatesView(*predicatesCollection))
if err != nil {
return err
}
Expand Down
9 changes: 5 additions & 4 deletions internal/commands/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/MakeNowJust/heredoc"
"github.com/checkmarx/ast-cli/internal/commands/commandutils"
"github.com/checkmarx/ast-cli/internal/commands/util"
"github.com/checkmarx/ast-cli/internal/commands/util/printer"
errorConstants "github.com/checkmarx/ast-cli/internal/constants/errors"
Expand Down Expand Up @@ -196,7 +197,7 @@ func NewProjectCommand(applicationsWrapper wrappers.ApplicationsWrapper, project
RunE: runGetProjectsTagsCommand(projectsWrapper),
}

addFormatFlagToMultipleCommands(
commandutils.AddFormatFlagToMultipleCommands(
[]*cobra.Command{showProjectCmd, listProjectsCmd, createProjCmd},
printer.FormatTable,
printer.FormatJSON,
Expand Down Expand Up @@ -281,7 +282,7 @@ func runCreateProjectCommand(
if errorModel != nil {
return errors.Errorf(services.ErrorCodeFormat, services.FailedCreatingProj, errorModel.Code, errorModel.Message)
} else if projResponseModel != nil {
err = printByFormat(cmd, toProjectView(*projResponseModel))
err = commandutils.PrintByFormat(cmd, toProjectView(*projResponseModel))
if err != nil {
return errors.Wrapf(err, "%s", services.FailedCreatingProj)
}
Expand Down Expand Up @@ -414,7 +415,7 @@ func runListProjectsCommand(projectsWrapper wrappers.ProjectsWrapper) func(cmd *
if errorModel != nil {
return errors.Errorf(services.ErrorCodeFormat, failedGettingAll, errorModel.Code, errorModel.Message)
} else if allProjectsModel != nil && allProjectsModel.Projects != nil {
err = printByFormat(cmd, toProjectViews(allProjectsModel.Projects))
err = commandutils.PrintByFormat(cmd, toProjectViews(allProjectsModel.Projects))
if err != nil {
return err
}
Expand Down Expand Up @@ -484,7 +485,7 @@ func runGetProjectByIDCommand(projectsWrapper wrappers.ProjectsWrapper) func(cmd
resp := GetProjectByName(projectResponseModel.Name, projectsWrapper)

projectResponseModel.Groups = resp.Groups
err = printByFormat(cmd, toProjectView(*projectResponseModel))
err = commandutils.PrintByFormat(cmd, toProjectView(*projectResponseModel))
if err != nil {
return err
}
Expand Down
Loading
Loading