mirror of
https://github.com/LukeHagar/sailpoint-cli.git
synced 2025-12-06 04:21:15 +00:00
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,6 +5,8 @@
|
||||
transform_files
|
||||
search_results
|
||||
spconfig-exports
|
||||
reports
|
||||
workflows
|
||||
|
||||
# CLI binary
|
||||
sailpoint-cli
|
||||
@@ -17,3 +19,4 @@ assets/demo_update.json
|
||||
cmd/transform/test_data/test_create.json
|
||||
cmd/transform/test_data/test_update.json
|
||||
example_transforms
|
||||
config.json
|
||||
|
||||
34
cmd/cluster/cluster.go
Normal file
34
cmd/cluster/cluster.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/cluster/logConfig"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed cluster.md
|
||||
var clusterHelp string
|
||||
|
||||
func NewClusterCommand() *cobra.Command {
|
||||
help := util.ParseHelp(clusterHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "cluster",
|
||||
Short: "Manage Clusters in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"cl"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newListCommand(),
|
||||
newGetCommand(),
|
||||
logConfig.NewLogCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
19
cmd/cluster/cluster.md
Normal file
19
cmd/cluster/cluster.md
Normal file
@@ -0,0 +1,19 @@
|
||||
==Long==
|
||||
# Cluster
|
||||
|
||||
Manage SailPoint IdentityNow Clusters
|
||||
|
||||
## API Reference:
|
||||
- https://developer.sailpoint.com/idn/api/beta/managed-clusters
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail cluster list
|
||||
|
||||
sail cluster get {cluster-id}
|
||||
sail cluster get {cluster-id} {cluster-id} ...
|
||||
|
||||
sail cluster log
|
||||
```
|
||||
====
|
||||
52
cmd/cluster/get.go
Normal file
52
cmd/cluster/get.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed get.md
|
||||
var getHelp string
|
||||
|
||||
func newGetCommand() *cobra.Command {
|
||||
help := util.ParseHelp(getHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get a Cluster from IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"get"},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
var output []*beta.ManagedCluster
|
||||
for _, id := range args {
|
||||
clusters, resp, clustersErr := apiClient.Beta.ManagedClustersApi.GetManagedCluster(context.TODO(), id).Execute()
|
||||
if clustersErr != nil {
|
||||
return sdk.HandleSDKError(resp, clustersErr)
|
||||
}
|
||||
|
||||
output = append(output, clusters)
|
||||
}
|
||||
cmd.Println(util.PrettyPrint(output))
|
||||
} else {
|
||||
cmd.Help()
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
16
cmd/cluster/get.md
Normal file
16
cmd/cluster/get.md
Normal file
@@ -0,0 +1,16 @@
|
||||
==Long==
|
||||
# Get
|
||||
|
||||
Get a clusters configuration from IdentityNow
|
||||
|
||||
## API References:
|
||||
- https://developer.sailpoint.com/idn/api/beta/get-managed-cluster
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail cluster get {cluster-id}
|
||||
sail cluster get {cluster-id} {cluster-id} ...
|
||||
```
|
||||
====
|
||||
52
cmd/cluster/list.go
Normal file
52
cmd/cluster/list.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
sailpoint "github.com/sailpoint-oss/golang-sdk"
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/output"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed list.md
|
||||
var listHelp string
|
||||
|
||||
func newListCommand() *cobra.Command {
|
||||
help := util.ParseHelp(listHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List the Clusters configured in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"ls"},
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clusters, resp, clustersErr := sailpoint.PaginateWithDefaults[beta.ManagedCluster](apiClient.Beta.ManagedClustersApi.GetManagedClusters(context.TODO()))
|
||||
if clustersErr != nil {
|
||||
return sdk.HandleSDKError(resp, clustersErr)
|
||||
}
|
||||
|
||||
var entries [][]string
|
||||
for _, cluster := range clusters {
|
||||
entries = append(entries, []string{*cluster.Name, *cluster.Org, cluster.Id})
|
||||
}
|
||||
|
||||
output.WriteTable(cmd.OutOrStdout(), []string{"Name", "Org", "ID"}, entries)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
15
cmd/cluster/list.md
Normal file
15
cmd/cluster/list.md
Normal file
@@ -0,0 +1,15 @@
|
||||
==Long==
|
||||
# List
|
||||
|
||||
List all clusters from IdentityNow
|
||||
|
||||
## API References:
|
||||
- https://developer.sailpoint.com/idn/api/beta/get-managed-clusters
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail cluster list
|
||||
```
|
||||
====
|
||||
@@ -2,47 +2,42 @@ package logConfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newGetCmd() *cobra.Command {
|
||||
//go:embed get.md
|
||||
var getHelp string
|
||||
|
||||
func newGetCommand() *cobra.Command {
|
||||
help := util.ParseHelp(getHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Return a Virtual Appliances log configuration",
|
||||
Long: "\nReturn a Virtual Appliances log configuration\n\n",
|
||||
Example: "sail va log get",
|
||||
Short: "Get a Virtual Appliances clusters log configuration",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
var output []beta.ClientLogConfiguration
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < len(args); i++ {
|
||||
|
||||
clusterId := args[i]
|
||||
for _, clusterId := range args {
|
||||
|
||||
configuration, resp, err := apiClient.Beta.ManagedClustersApi.GetClientLogConfiguration(context.TODO(), clusterId).Execute()
|
||||
if err != nil {
|
||||
return sdk.HandleSDKError(resp, err)
|
||||
}
|
||||
|
||||
if configuration != nil {
|
||||
output = append(output, *configuration)
|
||||
}
|
||||
|
||||
cmd.Println(util.PrettyPrint(configuration))
|
||||
}
|
||||
|
||||
cmd.Println(util.PrettyPrint(output))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
11
cmd/cluster/logConfig/get.md
Normal file
11
cmd/cluster/logConfig/get.md
Normal file
@@ -0,0 +1,11 @@
|
||||
==Long==
|
||||
# Get
|
||||
|
||||
Get a managed clusters log configuration
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail cluster log get 2c91808580f6cc1a01811af8cf5f18cb
|
||||
```
|
||||
====
|
||||
@@ -2,25 +2,31 @@
|
||||
package logConfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewLogCmd() *cobra.Command {
|
||||
//go:embed logConfig.md
|
||||
var logConfigHelp string
|
||||
|
||||
func NewLogCommand() *cobra.Command {
|
||||
help := util.ParseHelp(logConfigHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "log",
|
||||
Short: "Interact with a SailPoint Virtual Appliances log configuration",
|
||||
Long: "\nInteract with SailPoint Virtual Appliances log configuration\n\n",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"l"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newGetCmd(),
|
||||
newSetCmd(),
|
||||
newGetCommand(),
|
||||
newSetCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
16
cmd/cluster/logConfig/logConfig.md
Normal file
16
cmd/cluster/logConfig/logConfig.md
Normal file
@@ -0,0 +1,16 @@
|
||||
==Long==
|
||||
|
||||
# Log Config
|
||||
|
||||
Get or set a managed clusters log configuration
|
||||
|
||||
## API Reference:
|
||||
- https://developer.sailpoint.com/idn/api/beta/managed-clusters
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail cluster log get 2c91808580f6cc1a01811af8cf5f18cb
|
||||
sail cluster log set 2c91808580f6cc1a01811af8cf5f18cb -r TRACE -d 30 -c sailpoint.connector.ADLDAPConnector=TRACE
|
||||
```
|
||||
====
|
||||
@@ -2,6 +2,8 @@ package logConfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
@@ -12,7 +14,11 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newSetCmd() *cobra.Command {
|
||||
//go:embed set.md
|
||||
var setHelp string
|
||||
|
||||
func newSetCommand() *cobra.Command {
|
||||
help := util.ParseHelp(setHelp)
|
||||
var level string
|
||||
var durationInMinutes int32
|
||||
var connectors []string
|
||||
@@ -20,31 +26,30 @@ func newSetCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "Set a Virtual Appliances log configuration",
|
||||
Long: "\nSet a Virtual Appliances log configuration\n\nA list of Connectors can be found here:\nhttps://community.sailpoint.com/t5/IdentityNow-Articles/Enabling-Connector-Logging-in-IdentityNow/ta-p/188107\n\n",
|
||||
Example: "sail va log set",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
rootLevel := beta.StandardLevel(level)
|
||||
|
||||
if rootLevel.IsValid() == false {
|
||||
log.Fatal("logLevel provided is invalid", "level", level)
|
||||
if !rootLevel.IsValid() {
|
||||
return errors.New("invalid logLevel: " + level)
|
||||
|
||||
}
|
||||
|
||||
if durationInMinutes < 5 || durationInMinutes > 1440 {
|
||||
log.Fatal("durationInMinutes provided is invalid", "durationInMinutes", durationInMinutes)
|
||||
return errors.New("invalid durationInMinutes: " + string(durationInMinutes))
|
||||
}
|
||||
|
||||
var output []beta.ClientLogConfiguration
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logLevels := make(map[string]beta.StandardLevel)
|
||||
for j := 0; j < len(connectors); j++ {
|
||||
connector := connectors[j]
|
||||
|
||||
for _, connector := range connectors {
|
||||
parts := strings.Split(connector, "=")
|
||||
conLevel := beta.StandardLevel(parts[1])
|
||||
if conLevel.IsValid() {
|
||||
@@ -54,23 +59,16 @@ func newSetCmd() *cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
logConfig := beta.NewClientLogConfiguration(durationInMinutes, rootLevel)
|
||||
logConfig.LogLevels = &logLevels
|
||||
for _, clusterId := range args {
|
||||
|
||||
for i := 0; i < len(args); i++ {
|
||||
|
||||
clusterId := args[i]
|
||||
|
||||
configuration, resp, err := apiClient.Beta.ManagedClustersApi.PutClientLogConfiguration(context.TODO(), clusterId).ClientLogConfiguration(*logConfig).Execute()
|
||||
configuration, resp, err := apiClient.Beta.ManagedClustersApi.PutClientLogConfiguration(context.TODO(), clusterId).ClientLogConfiguration(beta.ClientLogConfiguration{DurationMinutes: durationInMinutes, RootLevel: rootLevel, LogLevels: &logLevels}).Execute()
|
||||
if err != nil {
|
||||
return sdk.HandleSDKError(resp, err)
|
||||
}
|
||||
|
||||
output = append(output, *configuration)
|
||||
cmd.Println(util.PrettyPrint(configuration))
|
||||
}
|
||||
|
||||
cmd.Println(util.PrettyPrint(output))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
13
cmd/cluster/logConfig/set.md
Normal file
13
cmd/cluster/logConfig/set.md
Normal file
@@ -0,0 +1,13 @@
|
||||
==Long==
|
||||
# Set
|
||||
|
||||
Set a managed clusters log configuration
|
||||
|
||||
A list of Connectors (can be found here)[https://community.sailpoint.com/t5/IdentityNow-Articles/Enabling-Connector-Logging-in-IdentityNow/ta-p/188107]
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail cluster log set 2c91808580f6cc1a01811af8cf5f18cb -r TRACE -d 30 -c sailpoint.connector.ADLDAPConnector=TRACE
|
||||
```
|
||||
====
|
||||
@@ -41,7 +41,7 @@ func NewConnCmd(term terminal.Terminal) *cobra.Command {
|
||||
conn.PersistentFlags().StringP("conn-endpoint", "e", connectorsEndpoint, "Override connectors endpoint")
|
||||
|
||||
conn.AddCommand(
|
||||
newConnInitCmd(),
|
||||
newConnInitCommand(),
|
||||
newConnListCmd(Client),
|
||||
newConnGetCmd(Client),
|
||||
newConnUpdateCmd(Client),
|
||||
|
||||
@@ -29,7 +29,7 @@ const (
|
||||
// newConnInitCmd is a connectors subcommand used to initialize a new connector project.
|
||||
// It accepts one argument, project name, and generates appropriate directories and files
|
||||
// to set up a working, sample project.
|
||||
func newConnInitCmd() *cobra.Command {
|
||||
func newConnInitCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "init <connector-name>",
|
||||
Short: "Initialize new connector project",
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func TestNewConnInitCmd_noArgs(t *testing.T) {
|
||||
cmd := newConnInitCmd()
|
||||
cmd := newConnInitCommand()
|
||||
cmd.SetArgs([]string{})
|
||||
|
||||
if err := cmd.Execute(); err == nil {
|
||||
@@ -20,7 +20,7 @@ func TestNewConnInitCmd_noArgs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewConnInitCmd_emptyName(t *testing.T) {
|
||||
cmd := newConnInitCmd()
|
||||
cmd := newConnInitCommand()
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
cmd.SetErr(b)
|
||||
@@ -42,7 +42,7 @@ func TestNewConnInitCmd_emptyName(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewConnInitCmd(t *testing.T) {
|
||||
cmd := newConnInitCmd()
|
||||
cmd := newConnInitCommand()
|
||||
|
||||
testProjName := "test-connector-project"
|
||||
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
package environment
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/tui"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
//go:embed environment.md
|
||||
var environmentHelp string
|
||||
|
||||
func NewEnvironmentCommand() *cobra.Command {
|
||||
help := util.ParseHelp(environmentHelp)
|
||||
var env string
|
||||
var overwrite bool
|
||||
var erase bool
|
||||
@@ -19,27 +24,18 @@ func NewEnvironmentCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "environment",
|
||||
Short: "Manage Environments for the CLI",
|
||||
Long: "\nManage Environments for the CLI\n\n",
|
||||
Example: "sail env dev",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"env"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
environments := config.GetEnvironments()
|
||||
envKeys := maps.Keys(environments)
|
||||
|
||||
if len(args) > 0 {
|
||||
env = args[0]
|
||||
} else {
|
||||
var choices []tui.Choice
|
||||
for i := 0; i < len(envKeys); i++ {
|
||||
choices = append(choices, tui.Choice{Title: envKeys[i]})
|
||||
}
|
||||
selectedEnv, err := tui.PromptList(choices, "Please select an existing environment: ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
env = selectedEnv.Title
|
||||
env = config.GetActiveEnvironment()
|
||||
}
|
||||
|
||||
if env != "" {
|
||||
@@ -49,8 +45,9 @@ func NewEnvironmentCommand() *cobra.Command {
|
||||
if show {
|
||||
log.Warn("You are about to Print out the Environment", "env", env)
|
||||
res := terminal.InputPrompt("Press Enter to continue")
|
||||
log.Info("Response", "res", res)
|
||||
if res == "" {
|
||||
util.PrettyPrint(foundEnv)
|
||||
fmt.Println(util.PrettyPrint(foundEnv))
|
||||
}
|
||||
} else if erase {
|
||||
log.Warn("You are about to Erase the Environment", "env", env)
|
||||
@@ -73,7 +70,7 @@ func NewEnvironmentCommand() *cobra.Command {
|
||||
|
||||
}
|
||||
} else {
|
||||
log.Warn("No Environment Provided")
|
||||
cmd.Help()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
48
cmd/environment/environment.md
Normal file
48
cmd/environment/environment.md
Normal file
@@ -0,0 +1,48 @@
|
||||
==Long==
|
||||
# Environment
|
||||
|
||||
Configure SailPoint IdentityNow environments for the CLI
|
||||
====
|
||||
|
||||
==Example==
|
||||
## Adding an new environment
|
||||
|
||||
You can add new environments by supplying a name that does not already exist. The CLI will prompt you for the Tenant URL and API URL.
|
||||
|
||||
```bash
|
||||
sail environment {environment-name}
|
||||
```
|
||||
|
||||
|
||||
## Switching environments
|
||||
|
||||
You can switch between environments by supplying the name of an existing environment you want to switch to.
|
||||
|
||||
```bash
|
||||
sail environment {environment-name}
|
||||
```
|
||||
|
||||
## Removing an environment
|
||||
|
||||
You can remove an environment by supplying the name of an existing environment you want to remove in combination with the `--erase` flag.
|
||||
|
||||
```bash
|
||||
sail environment {environment-name} --erase
|
||||
```
|
||||
|
||||
## Overwriting an environment
|
||||
|
||||
You can overwrite an environment by supplying the name of an existing environment you want to overwrite in combination with the `--overwrite` flag.
|
||||
|
||||
```bash
|
||||
sail environment {environment-name} --overwrite
|
||||
```
|
||||
|
||||
## Showing an environment
|
||||
|
||||
You can print an environment by supplying the name of an existing environment you want to print in combination with the `--show` flag.
|
||||
|
||||
```bash
|
||||
sail environment {environment-name} --show
|
||||
```
|
||||
====
|
||||
@@ -2,27 +2,126 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
v3 "github.com/sailpoint-oss/golang-sdk/v3"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/output"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/templates"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/types"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed report.md
|
||||
var reportHelp string
|
||||
|
||||
func NewReportCommand() *cobra.Command {
|
||||
help := util.ParseHelp(reportHelp)
|
||||
var save bool
|
||||
var folderPath string
|
||||
var template string
|
||||
cmd := &cobra.Command{
|
||||
Use: "report",
|
||||
Short: "Generate a report from a template using IdentityNow search queries",
|
||||
Long: "Generate a report from a template using IdentityNow search queries",
|
||||
Example: "sail report \"\"",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"rep"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
err := config.InitConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var selectedTemplate templates.ReportTemplate
|
||||
reportTemplates, err := templates.GetReportTemplates()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
template = args[0]
|
||||
} else {
|
||||
template, err = templates.SelectTemplate(reportTemplates)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if template == "" {
|
||||
return fmt.Errorf("no template specified")
|
||||
}
|
||||
|
||||
log.Info("Selected Template", "template", template)
|
||||
|
||||
matches := types.Filter(reportTemplates, func(st templates.ReportTemplate) bool { return st.Name == template })
|
||||
if len(matches) < 1 {
|
||||
return fmt.Errorf("no template matches for %s", template)
|
||||
} else if len(matches) > 1 {
|
||||
log.Warn("multiple template matches, the first match will be used", "template", template)
|
||||
}
|
||||
selectedTemplate = matches[0]
|
||||
|
||||
if len(selectedTemplate.Variables) > 0 {
|
||||
for _, varEntry := range selectedTemplate.Variables {
|
||||
|
||||
resp := terminal.InputPrompt("Input " + varEntry.Prompt + ":")
|
||||
selectedTemplate.Raw = []byte(strings.ReplaceAll(string(selectedTemplate.Raw), "{{"+varEntry.Name+"}}", resp))
|
||||
}
|
||||
err := json.Unmarshal(selectedTemplate.Raw, &selectedTemplate.Queries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for i, currentQuery := range selectedTemplate.Queries {
|
||||
|
||||
searchQuery := v3.NewSearch()
|
||||
query := v3.NewQuery()
|
||||
query.SetQuery(currentQuery.QueryString)
|
||||
searchQuery.Query = query
|
||||
|
||||
resp, err := apiClient.V3.SearchApi.SearchCount(context.TODO()).Search(*searchQuery).Execute()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", resp)
|
||||
}
|
||||
selectedTemplate.Queries[i].ResultCount = resp.Header["X-Total-Count"][0]
|
||||
}
|
||||
|
||||
if save {
|
||||
fileName := selectedTemplate.Name + ".json"
|
||||
err := output.SaveJSONFile(selectedTemplate.Queries, fileName, folderPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info("Report saved", "path", path.Join(folderPath, fileName))
|
||||
|
||||
} else {
|
||||
cmd.Println(util.PrettyPrint(selectedTemplate.Queries))
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newTemplateCmd(),
|
||||
)
|
||||
cmd.Flags().BoolVarP(&save, "save", "s", false, "save the report to a file")
|
||||
cmd.Flags().StringVarP(&folderPath, "folderPath", "f", "reports", "folder path to save the reports in. If the directory doesn't exist, then it will be automatically created. (default is the current working directory)")
|
||||
|
||||
return cmd
|
||||
|
||||
|
||||
21
cmd/report/report.md
Normal file
21
cmd/report/report.md
Normal file
@@ -0,0 +1,21 @@
|
||||
==Long==
|
||||
# Report
|
||||
|
||||
Generate a report from IdentityNow
|
||||
|
||||
## API References:
|
||||
- https://developer.sailpoint.com/idn/api/v3/search
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
## Selecting a report
|
||||
```bash
|
||||
sail report
|
||||
```
|
||||
|
||||
## Running a specific report
|
||||
```bash
|
||||
sail report {report-name}
|
||||
```
|
||||
====
|
||||
@@ -1,113 +0,0 @@
|
||||
// Copyright (c) 2021, SailPoint Technologies, Inc. All rights reserved.
|
||||
package report
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
v3 "github.com/sailpoint-oss/golang-sdk/v3"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/templates"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/types"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newTemplateCmd() *cobra.Command {
|
||||
var outputTypes []string
|
||||
var folderPath string
|
||||
var template string
|
||||
cmd := &cobra.Command{
|
||||
Use: "template",
|
||||
Short: "generate a report using a template",
|
||||
Long: "generate a report from IdentityNow using a template",
|
||||
Example: "sail report template",
|
||||
Aliases: []string{"temp"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
err := config.InitConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var selectedTemplate templates.ReportTemplate
|
||||
reportTemplates, err := templates.GetReportTemplates()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
template = args[0]
|
||||
} else {
|
||||
template, err = templates.SelectTemplate(reportTemplates)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if template == "" {
|
||||
return fmt.Errorf("no template specified")
|
||||
}
|
||||
|
||||
log.Info("Selected Template", "template", template)
|
||||
|
||||
matches := types.Filter(reportTemplates, func(st templates.ReportTemplate) bool { return st.Name == template })
|
||||
if len(matches) < 1 {
|
||||
return fmt.Errorf("no template matches for %s", template)
|
||||
} else if len(matches) > 1 {
|
||||
log.Warn("multiple template matches, the first match will be used", "template", template)
|
||||
}
|
||||
selectedTemplate = matches[0]
|
||||
varCount := len(selectedTemplate.Variables)
|
||||
if varCount > 0 {
|
||||
for i := 0; i < varCount; i++ {
|
||||
varEntry := selectedTemplate.Variables[i]
|
||||
resp := terminal.InputPrompt("Input " + varEntry.Prompt + ":")
|
||||
selectedTemplate.Raw = []byte(strings.ReplaceAll(string(selectedTemplate.Raw), "{{"+varEntry.Name+"}}", resp))
|
||||
}
|
||||
err := json.Unmarshal(selectedTemplate.Raw, &selectedTemplate.Queries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(selectedTemplate.Queries); i++ {
|
||||
|
||||
currentQuery := selectedTemplate.Queries[i]
|
||||
|
||||
searchQuery := v3.NewSearch()
|
||||
query := v3.NewQuery()
|
||||
query.SetQuery(currentQuery.QueryString)
|
||||
searchQuery.Query = query
|
||||
|
||||
resp, err := apiClient.V3.SearchApi.SearchCount(context.TODO()).Search(*searchQuery).Execute()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", resp)
|
||||
}
|
||||
selectedTemplate.Queries[i].ResultCount = resp.Header["X-Total-Count"][0]
|
||||
}
|
||||
|
||||
for i := 0; i < len(selectedTemplate.Queries); i++ {
|
||||
currentQuery := selectedTemplate.Queries[i]
|
||||
fmt.Println(currentQuery.QueryTitle + ": " + currentQuery.ResultCount)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringArrayVarP(&outputTypes, "output", "o", []string{"json"}, "the sort value for the api call (examples)")
|
||||
cmd.Flags().StringVarP(&folderPath, "folderPath", "f", "reports", "folder path to save the reports in. If the directory doesn't exist, then it will be automatically created. (default is the current working directory)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -1,28 +1,38 @@
|
||||
// Copyright (c) 2021, SailPoint Technologies, Inc. All rights reserved.
|
||||
package root
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/configure"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/cluster"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/connector"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/environment"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/report"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/search"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/set"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/spconfig"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/transform"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/va"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/workflow"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var version = "1.2.0"
|
||||
|
||||
func NewRootCmd() *cobra.Command {
|
||||
//go:embed root.md
|
||||
var rootHelp string
|
||||
|
||||
func NewRootCommand() *cobra.Command {
|
||||
help := util.ParseHelp(rootHelp)
|
||||
var env string
|
||||
var debug bool
|
||||
root := &cobra.Command{
|
||||
Use: "sail",
|
||||
Short: "The SailPoint CLI allows you to administer your IdentityNow tenant from the command line.\nNavigate to https://developer.sailpoint.com/idn/tools/cli to learn more.",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Version: version,
|
||||
SilenceUsage: true,
|
||||
CompletionOptions: cobra.CompletionOptions{
|
||||
@@ -31,22 +41,30 @@ func NewRootCmd() *cobra.Command {
|
||||
DisableDescriptions: true,
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
t := &terminal.Term{}
|
||||
|
||||
root.AddCommand(
|
||||
set.NewSetCommand(),
|
||||
environment.NewEnvironmentCommand(),
|
||||
configure.NewConfigureCmd(t),
|
||||
cluster.NewClusterCommand(),
|
||||
connector.NewConnCmd(t),
|
||||
transform.NewTransformCmd(),
|
||||
va.NewVACmd(t),
|
||||
search.NewSearchCmd(),
|
||||
spconfig.NewSPConfigCmd(),
|
||||
environment.NewEnvironmentCommand(),
|
||||
report.NewReportCommand(),
|
||||
sdk.NewSDKCommand(),
|
||||
search.NewSearchCommand(),
|
||||
set.NewSetCmd(t),
|
||||
spconfig.NewSPConfigCommand(),
|
||||
transform.NewTransformCommand(),
|
||||
va.NewVACommand(t),
|
||||
workflow.NewWorkflowCommand(),
|
||||
)
|
||||
|
||||
root.PersistentFlags().StringVarP(&env, "env", "", "", "Environment to use for SailPoint CLI commands")
|
||||
root.PersistentFlags().BoolVarP(&debug, "debug", "", false, "Enable debug logging")
|
||||
viper.BindPFlag("activeenvironment", root.PersistentFlags().Lookup("env"))
|
||||
viper.BindPFlag("debug", root.PersistentFlags().Lookup("debug"))
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
13
cmd/root/root.md
Normal file
13
cmd/root/root.md
Normal file
@@ -0,0 +1,13 @@
|
||||
==Long==
|
||||
# SailPoint CLI
|
||||
The SailPoint CLI allows you to administer your IdentityNow tenant from the command line.
|
||||
|
||||
Navigate to the [CLI Documentation](https://developer.sailpoint.com/idn/tools/cli) for more information.
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail
|
||||
```
|
||||
====
|
||||
@@ -5,6 +5,7 @@ package root
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@@ -12,16 +13,16 @@ import (
|
||||
|
||||
// Expected number of subcommands to `sail` root command
|
||||
const (
|
||||
numRootSubcommands = 9
|
||||
numRootSubcommands = 11
|
||||
)
|
||||
|
||||
func TestNewRootCmd_noArgs(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
cmd := NewRootCmd()
|
||||
cmd := NewRootCommand()
|
||||
if len(cmd.Commands()) != numRootSubcommands {
|
||||
t.Fatalf("expected: %d, actual: %d", len(cmd.Commands()), numRootSubcommands)
|
||||
t.Fatalf("expected: %d, actual: %d", numRootSubcommands, len(cmd.Commands()))
|
||||
}
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
@@ -38,7 +39,7 @@ func TestNewRootCmd_noArgs(t *testing.T) {
|
||||
t.Fatalf("error read out: %v", err)
|
||||
}
|
||||
|
||||
if string(out) != cmd.UsageString() {
|
||||
if !strings.Contains(string(out), cmd.UsageString()) {
|
||||
t.Errorf("expected: %s, actual: %s", cmd.UsageString(), string(out))
|
||||
}
|
||||
}
|
||||
@@ -47,7 +48,7 @@ func TestNewRootCmd_completionDisabled(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
cmd := NewRootCmd()
|
||||
cmd := NewRootCommand()
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
cmd.SetOut(b)
|
||||
|
||||
94
cmd/sdk/config.go
Normal file
94
cmd/sdk/config.go
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
BaseUrl string
|
||||
}
|
||||
|
||||
func (c Config) printEnv() {
|
||||
fmt.Println("BASE_URL=" + c.BaseUrl)
|
||||
fmt.Println("CLIENT_ID=" + c.ClientID)
|
||||
fmt.Println("CLIENT_SECRET=" + c.ClientSecret)
|
||||
}
|
||||
|
||||
func newConfigCommand() *cobra.Command {
|
||||
var env bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "config",
|
||||
Short: "Initialize a configuration json file for an SDK project",
|
||||
Long: "\nInitialize a configuration json file for an SDK project\n\nRunning with no arguments will use the currently active environment\n",
|
||||
Example: "sail sdk init config\nsail sdk init config <environment name>",
|
||||
Aliases: []string{"conf"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
var envName string
|
||||
if len(args) > 0 {
|
||||
envName = args[0]
|
||||
} else {
|
||||
envName = config.GetActiveEnvironment()
|
||||
}
|
||||
|
||||
clientID, err := config.GetClientID(envName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clientSecret, err := config.GetClientSecret(envName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
SDKConfig := Config{ClientID: clientID, ClientSecret: clientSecret, BaseUrl: config.GetEnvBaseUrl(envName)}
|
||||
|
||||
if env {
|
||||
SDKConfig.printEnv()
|
||||
} else {
|
||||
workingDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
configPath := path.Join(workingDir, "config.json")
|
||||
|
||||
file, err := os.Create(configPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
configJson, err := json.MarshalIndent(SDKConfig, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = file.Write(configJson)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info("config file created", "path", configPath)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&env, "environment", "e", false, "Print out the config values in .env format to the terminal rather than to a config file")
|
||||
|
||||
return cmd
|
||||
}
|
||||
44
cmd/sdk/go.go
Normal file
44
cmd/sdk/go.go
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/initialize"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed golang/*
|
||||
var goTemplateContents embed.FS
|
||||
|
||||
const goTemplateDirName = "golang"
|
||||
|
||||
func newGolangCommand() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "golang",
|
||||
Short: "Initialize a new GO SDK project",
|
||||
Long: "\nInitialize a new GO SDK project\n\n",
|
||||
Example: "sail sdk init golang\nsail sdk init go example-project",
|
||||
Aliases: []string{"go"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var projName string
|
||||
var err error
|
||||
|
||||
if len(args) > 0 {
|
||||
projName = args[0]
|
||||
} else {
|
||||
projName = "go-template"
|
||||
}
|
||||
|
||||
err = initialize.InitializeProject(goTemplateContents, goTemplateDirName, projName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
30
cmd/sdk/golang/go.mod.file
Normal file
30
cmd/sdk/golang/go.mod.file
Normal file
@@ -0,0 +1,30 @@
|
||||
module sdk
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/sailpoint-oss/golang-sdk v1.0.1
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/spf13/afero v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.15.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
golang.org/x/net v0.6.0 // indirect
|
||||
golang.org/x/oauth2 v0.5.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
501
cmd/sdk/golang/go.sum
Normal file
501
cmd/sdk/golang/go.sum
Normal file
@@ -0,0 +1,501 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.1 h1:JFqoW5K7/RkwzqhEnh0bJfcDc5CDAwrf9TxXnYqK/Ho=
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.1/go.mod h1:aMxZu5ieAI89duSsOy/R7+dXwk5EbF6CAEvXt8ivMYw=
|
||||
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
|
||||
github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
||||
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
94
cmd/sdk/golang/sdk.go
Normal file
94
cmd/sdk/golang/sdk.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
sailpoint "github.com/sailpoint-oss/golang-sdk"
|
||||
v3 "github.com/sailpoint-oss/golang-sdk/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
configuration := sailpoint.NewDefaultConfiguration()
|
||||
|
||||
apiClient := sailpoint.NewAPIClient(configuration)
|
||||
configuration.HTTPClient.RetryMax = 10
|
||||
|
||||
getBeta(ctx, apiClient)
|
||||
|
||||
//getAllPaginatedResults(ctx, apiClient)
|
||||
|
||||
}
|
||||
|
||||
func getResults(ctx context.Context, apiClient *sailpoint.APIClient) {
|
||||
resp, r, err := apiClient.V3.AccountsApi.ListAccounts(ctx).Execute()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error when calling `AccountsApi.ListAccount``: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
|
||||
}
|
||||
// response from `ListAccounts`: []Account
|
||||
fmt.Fprintf(os.Stdout, "First response from `AccountsApi.ListAccount`: %v\n", resp[0].Name)
|
||||
}
|
||||
|
||||
func getSearchResults(ctx context.Context, apiClient *sailpoint.APIClient) {
|
||||
search := v3.NewSearchWithDefaults()
|
||||
search.Indices = append(search.Indices, "identities")
|
||||
searchString := []byte(`
|
||||
{
|
||||
"indices": [
|
||||
"identities"
|
||||
],
|
||||
"query": {
|
||||
"query": "*"
|
||||
},
|
||||
"sort": [
|
||||
"-name"
|
||||
]
|
||||
}
|
||||
`)
|
||||
search.UnmarshalJSON(searchString)
|
||||
resp, r, err := sailpoint.PaginateSearchApi(ctx, apiClient, *search, 0, 10, 10000)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error when calling `AccountsApi.ListAccount``: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
|
||||
}
|
||||
// response from `search`
|
||||
for i := 0; i < len(resp); i++ {
|
||||
fmt.Println(resp[i]["name"])
|
||||
}
|
||||
}
|
||||
|
||||
func getTransformResults(ctx context.Context, apiClient *sailpoint.APIClient) {
|
||||
resp, r, err := apiClient.V3.TransformsApi.ListTransforms(ctx).Execute()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error when calling `TransformsApi.GetTransformsList``: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
|
||||
}
|
||||
b, _ := json.Marshal(resp[0].Attributes)
|
||||
fmt.Fprintf(os.Stdout, "First response from `TransformsApi.GetTransformsList`: %v\n", string(b))
|
||||
}
|
||||
|
||||
func getAllPaginatedResults(ctx context.Context, apiClient *sailpoint.APIClient) {
|
||||
resp, r, err := sailpoint.PaginateWithDefaults[v3.Account](apiClient.V3.AccountsApi.ListAccounts(ctx))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error when calling `AccountsApi.ListAccount``: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
|
||||
}
|
||||
// response from `ListAccounts`: []Account
|
||||
fmt.Fprintf(os.Stdout, "First response from `AccountsApi.ListAccount`: %v\n", resp[0].Name)
|
||||
}
|
||||
|
||||
func getBeta(ctx context.Context, apiClient *sailpoint.APIClient) {
|
||||
resp, _, err := apiClient.Beta.AccountsApi.ListAccounts(context.TODO()).Execute()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error when calling `AccountsApi.ListAccount``: %v\n", err)
|
||||
//fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
|
||||
}
|
||||
// response from `ListAccounts`: []Account
|
||||
fmt.Fprintf(os.Stdout, "First response from `AccountsApi.ListAccount`: %v\n", resp)
|
||||
}
|
||||
30
cmd/sdk/init.go
Normal file
30
cmd/sdk/init.go
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newInitCommand() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "init",
|
||||
Short: "Initialize SDK projects",
|
||||
Long: "\nInitialize SDK projects\n\n",
|
||||
Example: "sail sdk init",
|
||||
Aliases: []string{"temp"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newTypescriptCommand(),
|
||||
newGolangCommand(),
|
||||
newPowerShellCommand(),
|
||||
newConfigCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
28
cmd/sdk/powershell/paginate.ps1
Normal file
28
cmd/sdk/powershell/paginate.ps1
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
$JSON = @"
|
||||
{
|
||||
"indices": [
|
||||
"identities"
|
||||
],
|
||||
"query": {
|
||||
"query": "*",
|
||||
"fields": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"sort": [
|
||||
"-displayName"
|
||||
]
|
||||
}
|
||||
"@
|
||||
|
||||
$Search = ConvertFrom-JsonToSearch -Json $JSON
|
||||
|
||||
try {
|
||||
|
||||
Invoke-PaginateSearch -Increment 50 -Limit 10000 -Search $Search
|
||||
|
||||
} catch {
|
||||
Write-Host ("Exception occurred when calling Invoke-PaginateSearch: {0}" -f $_.ErrorDetails)
|
||||
Write-Host ("Response headers: {0}" -f $_.Exception.Response.Headers)
|
||||
}
|
||||
14
cmd/sdk/powershell/paginateAccounts.ps1
Normal file
14
cmd/sdk/powershell/paginateAccounts.ps1
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
$Parameters = @{
|
||||
"Filters" = 'name co "Andrew"'
|
||||
}
|
||||
|
||||
# Accounts List
|
||||
try {
|
||||
|
||||
Invoke-Paginate -Function "Get-Accounts" -Increment 250 -Limit 1000 -InitialOffset 0 -Parameters $Parameters
|
||||
|
||||
} catch {
|
||||
Write-Host ("Exception occurred when calling Invoke-Paginate: {0}" -f $_.ErrorDetails)
|
||||
Write-Host ("Response headers: {0}" -f $_.Exception.Response.Headers)
|
||||
}
|
||||
14
cmd/sdk/powershell/patchEntitlement.ps1
Normal file
14
cmd/sdk/powershell/patchEntitlement.ps1
Normal file
@@ -0,0 +1,14 @@
|
||||
$ENT = @(
|
||||
@{
|
||||
op = "replace"
|
||||
path = "/privileged"
|
||||
value = $false
|
||||
}
|
||||
)
|
||||
|
||||
try {
|
||||
Update-BetaEntitlement -Id "2c9180848366cdc701837b78f5ce58be" -JsonPatchOperation $ENT
|
||||
} catch {
|
||||
Write-Host ("Exception occurred when calling Update-BetaEntitlement: {0}" -f $_.ErrorDetails)
|
||||
Write-Host ("Response headers: {0}" -f $_.Exception.Response.Headers)
|
||||
}
|
||||
14
cmd/sdk/powershell/sdk.ps1
Normal file
14
cmd/sdk/powershell/sdk.ps1
Normal file
@@ -0,0 +1,14 @@
|
||||
$Limit = 250 # Int32 | Max number of results to return. See [V3 API Standard Collection Parameters](https://developer.sailpoint.com/idn/api/standard-collection-parameters) for more information. (optional) (default to 250)
|
||||
$Offset = 0 # Int32 | Offset into the full result set. Usually specified with *limit* to paginate through the results. See [V3 API Standard Collection Parameters](https://developer.sailpoint.com/idn/api/standard-collection-parameters) for more information. (optional) (default to 0)
|
||||
$Count = $true # Boolean | If *true* it will populate the *X-Total-Count* response header with the number of results that would be returned if *limit* and *offset* were ignored. Since requesting a total count can have a performance impact, it is recommended not to send **count=true** if that value will not be used. See [V3 API Standard Collection Parameters](https://developer.sailpoint.com/idn/api/standard-collection-parameters) for more information. (optional) (default to $false)
|
||||
$Filters = 'sourceId eq "f4e73766efdf4dc6acdeed179606d694"' # String | Filter results using the standard syntax described in [V3 API Standard Collection Parameters](https://developer.sailpoint.com/idn/api/standard-collection-parameters#filtering-results) Filtering is supported for the following fields and operators: **id**: *eq, in* **identityId**: *eq* **name**: *eq, in* **nativeIdentity**: *eq, in* **sourceId**: *eq, in* **uncorrelated**: *eq* (optional)
|
||||
|
||||
# Accounts List
|
||||
try {
|
||||
|
||||
Get-Accounts -Limit $Limit -Offset $Offset -Count $Count -Filters $Filters
|
||||
|
||||
} catch {
|
||||
Write-Host ("Exception occurred when calling Get-Accounts: {0}" -f $_.ErrorDetails)
|
||||
Write-Host ("Response headers: {0}" -f $_.Exception.Response.Headers)
|
||||
}
|
||||
22
cmd/sdk/powershell/search.ps1
Normal file
22
cmd/sdk/powershell/search.ps1
Normal file
@@ -0,0 +1,22 @@
|
||||
$Json = @"
|
||||
{
|
||||
"indices": [
|
||||
"identities"
|
||||
],
|
||||
"query": {
|
||||
"query": "*",
|
||||
"fields": [
|
||||
"name"
|
||||
]
|
||||
}
|
||||
}
|
||||
"@
|
||||
|
||||
$Search = ConvertFrom-JsonToSearch -Json $Json
|
||||
|
||||
try {
|
||||
Search-Post -Search $Search
|
||||
} catch {
|
||||
Write-Host ("Exception occurred when calling Search-Post: {0}" -f $_.ErrorDetails)
|
||||
Write-Host ("Response headers: {0}" -f $_.Exception.Response.Headers)
|
||||
}
|
||||
24
cmd/sdk/powershell/transform.ps1
Normal file
24
cmd/sdk/powershell/transform.ps1
Normal file
@@ -0,0 +1,24 @@
|
||||
# Create transform
|
||||
$JSON = @"
|
||||
{
|
||||
"name": "New Transform",
|
||||
"type": "lookup",
|
||||
"attributes" : {
|
||||
"table" : {
|
||||
"USA": "Americas",
|
||||
"FRA": "EMEA",
|
||||
"AUS": "APAC",
|
||||
"default": "Unknown Region"
|
||||
}
|
||||
}
|
||||
}
|
||||
"@
|
||||
|
||||
$Transform = ConvertFrom-JsonToTransform -Json $JSON
|
||||
|
||||
try {
|
||||
New-Transform -Transform $Transform
|
||||
} catch {
|
||||
Write-Host ("Exception occurred when calling New-Transform: {0}" -f $_.ErrorDetails)
|
||||
Write-Host ("Response headers: {0}" -f $_.Exception.Response.Headers)
|
||||
}
|
||||
44
cmd/sdk/pwsh.go
Normal file
44
cmd/sdk/pwsh.go
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/initialize"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed powershell/*
|
||||
var pwshTemplateContents embed.FS
|
||||
|
||||
const pwshTemplateDirName = "powershell"
|
||||
|
||||
func newPowerShellCommand() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "powershell",
|
||||
Short: "Initialize a new PowerShell SDK project",
|
||||
Long: "\nInitialize a new PowerShell SDK project\n\n",
|
||||
Example: "sail sdk init powershell\nsail sdk init pwsh example-project",
|
||||
Aliases: []string{"pwsh"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var projName string
|
||||
var err error
|
||||
|
||||
if len(args) > 0 {
|
||||
projName = args[0]
|
||||
} else {
|
||||
projName = "powershell-template"
|
||||
}
|
||||
|
||||
err = initialize.InitializeProject(pwshTemplateContents, pwshTemplateDirName, projName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
26
cmd/sdk/sdk.go
Normal file
26
cmd/sdk/sdk.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewSDKCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "sdk",
|
||||
Short: "Initialize or configure SDK projects",
|
||||
Long: "\nInitialize or configure SDK projects\n\n",
|
||||
Example: "sail sdk",
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newInitCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
||||
}
|
||||
44
cmd/sdk/ts.go
Normal file
44
cmd/sdk/ts.go
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/initialize"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed typescript/*
|
||||
var tsTemplateContents embed.FS
|
||||
|
||||
const tsTemplateDirName = "typescript"
|
||||
|
||||
func newTypescriptCommand() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "typescript",
|
||||
Short: "Initialize a new typescript SDK project",
|
||||
Long: "\nInitialize a new typescript SDK project\n\n",
|
||||
Example: "sail sdk init typescript\nsail sdk init ts example-project",
|
||||
Aliases: []string{"ts"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var projName string
|
||||
var err error
|
||||
|
||||
if len(args) > 0 {
|
||||
projName = args[0]
|
||||
} else {
|
||||
projName = "typescript-template"
|
||||
}
|
||||
|
||||
err = initialize.InitializeProject(tsTemplateContents, tsTemplateDirName, projName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
16
cmd/sdk/typescript/package.json
Normal file
16
cmd/sdk/typescript/package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "sailpoint-sdk",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
"scripts": {
|
||||
"start": "ts-node src/index.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.7.4",
|
||||
"sailpoint-api-client": "^1.0.4"
|
||||
}
|
||||
}
|
||||
85
cmd/sdk/typescript/src/index.ts
Normal file
85
cmd/sdk/typescript/src/index.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { AccountsApi, Configuration, axiosRetry, Paginator, SearchApi, TransformsApi, TransformsApiCreateTransformRequest, Search, IdentityDocument} from "sailpoint-api-client"
|
||||
|
||||
const createTransform = async () => {
|
||||
|
||||
let apiConfig = new Configuration()
|
||||
let api = new TransformsApi(apiConfig)
|
||||
let transform: TransformsApiCreateTransformRequest =
|
||||
{
|
||||
transform:
|
||||
{
|
||||
name: "Test Transform",
|
||||
type: "dateFormat",
|
||||
attributes: {
|
||||
inputFormat: "MMM dd yyyy, HH:mm:ss.SSS",
|
||||
outputFormat: "yyyy/dd/MM"
|
||||
}
|
||||
}
|
||||
}
|
||||
const val = await api.createTransform(transform)
|
||||
console.log(val)
|
||||
}
|
||||
|
||||
const search = async () => {
|
||||
let apiConfig = new Configuration()
|
||||
let api = new SearchApi(apiConfig)
|
||||
let search: Search = {
|
||||
indices: [
|
||||
"identities"
|
||||
],
|
||||
query: {
|
||||
query: "*"
|
||||
},
|
||||
sort: ["-name"]
|
||||
}
|
||||
const val = await Paginator.paginateSearchApi(api, search, 100, 1000)
|
||||
|
||||
for (const result of val.data) {
|
||||
const castedResult: IdentityDocument = result
|
||||
console.log(castedResult.name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const getPaginatedAccounts = async () => {
|
||||
|
||||
|
||||
let apiConfig = new Configuration()
|
||||
apiConfig.retriesConfig = {
|
||||
retries: 4,
|
||||
retryDelay: axiosRetry.exponentialDelay,
|
||||
onRetry(retryCount, error, requestConfig) {
|
||||
console.log(`retrying due to request error, try number ${retryCount}`)
|
||||
},
|
||||
}
|
||||
let api = new AccountsApi(apiConfig)
|
||||
|
||||
const val = await Paginator.paginate(api, api.listAccounts, {limit: 100}, 10)
|
||||
|
||||
console.log(val)
|
||||
|
||||
}
|
||||
|
||||
|
||||
const getPaginatedTransforms = async () => {
|
||||
|
||||
|
||||
let apiConfig = new Configuration()
|
||||
apiConfig.retriesConfig = {
|
||||
retries: 4,
|
||||
retryDelay: axiosRetry.exponentialDelay,
|
||||
onRetry(retryCount, error, requestConfig) {
|
||||
console.log(`retrying due to request error, try number ${retryCount}`)
|
||||
},
|
||||
}
|
||||
let api = new TransformsApi(apiConfig)
|
||||
|
||||
const val = await Paginator.paginate(api, api.listTransforms, {limit: 250}, 100)
|
||||
|
||||
console.log(val.data.length)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
getPaginatedTransforms()
|
||||
16
cmd/sdk/typescript/tsconfig.json
Normal file
16
cmd/sdk/typescript/tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
"skipLibCheck": true,
|
||||
"outDir": "./build",
|
||||
"rootDir": "src",
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -7,22 +7,29 @@ import (
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/search"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newQueryCmd() *cobra.Command {
|
||||
var folderPath string
|
||||
func newQueryCmd(folderPath string, save bool) *cobra.Command {
|
||||
|
||||
var indices []string
|
||||
var outputTypes []string
|
||||
|
||||
var sort []string
|
||||
var searchQuery string
|
||||
cmd := &cobra.Command{
|
||||
Use: "query",
|
||||
Short: "Manually Search using a specific Query and Indicies",
|
||||
Long: "\nRun a search query in IdentityNow using a specific Query and Indicies\n\n",
|
||||
Example: "sail search query \"(type:provisioning AND created:[now-90d TO now])\" --indicies events",
|
||||
Example: "sail search query \"(type:provisioning AND created:[now-90d TO now])\" --indices events",
|
||||
Aliases: []string{"que"},
|
||||
Args: cobra.ExactArgs(1),
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
folderPath, _ := cmd.Flags().GetString("folderPath")
|
||||
if folderPath == "" {
|
||||
cmd.MarkFlagRequired("save")
|
||||
}
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
err := config.InitConfig()
|
||||
@@ -50,20 +57,21 @@ func newQueryCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
err = search.IterateIndices(formattedResponse, searchQuery, folderPath, outputTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
if save {
|
||||
err = search.IterateIndices(formattedResponse, searchQuery, folderPath, []string{"json"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
cmd.Println(util.PrettyPrint(formattedResponse))
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringArrayVarP(&indices, "indices", "i", []string{}, "indices to perform the search query on (accessprofiles, accountactivities, entitlements, events, identities, roles)")
|
||||
cmd.Flags().StringArrayVarP(&sort, "sort", "s", []string{}, "the sort value for the api call (displayName, +id...)")
|
||||
cmd.Flags().StringArrayVarP(&outputTypes, "outputTypes", "o", []string{"json"}, "the output types for the results (csv, json)")
|
||||
cmd.Flags().StringVarP(&folderPath, "folderPath", "f", "search_results", "folder path to save the search results in. If the directory doesn't exist, then it will be automatically created. (default is the current working directory)")
|
||||
|
||||
cmd.Flags().StringArrayVar(&indices, "indices", []string{}, "indices to perform the search query on (accessprofiles, accountactivities, entitlements, events, identities, roles)")
|
||||
cmd.Flags().StringArrayVar(&sort, "sort", []string{}, "the sort value for the api call (displayName, +id...)")
|
||||
cmd.MarkFlagRequired("indices")
|
||||
|
||||
return cmd
|
||||
|
||||
@@ -2,29 +2,32 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewSearchCmd() *cobra.Command {
|
||||
func NewSearchCommand() *cobra.Command {
|
||||
var folderPath string
|
||||
var save bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "search",
|
||||
Short: "Perform Search operations in IdentityNow with a specific query or a template",
|
||||
Long: "\nPerform Search operations in IdentityNow with a specific query or a template\n\n",
|
||||
Example: "sail search -h",
|
||||
Example: "sail search",
|
||||
Aliases: []string{"se"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newQueryCmd(),
|
||||
newTemplateCmd(),
|
||||
newQueryCmd(folderPath, save),
|
||||
newTemplateCmd(folderPath, save),
|
||||
)
|
||||
|
||||
cmd.PersistentFlags().StringVarP(&folderPath, "folderPath", "f", "", "Folder path to save the search results to. If the directory doesn't exist, then it will be created. (defaults to the current working directory)")
|
||||
cmd.PersistentFlags().BoolVarP(&save, "save", "s", false, "Save the search results to a file")
|
||||
|
||||
return cmd
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func TestNewSearchCommand(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
cmd := NewSearchCmd()
|
||||
cmd := NewSearchCommand()
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
cmd.SetOut(b)
|
||||
|
||||
@@ -12,12 +12,11 @@ import (
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/templates"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/types"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newTemplateCmd() *cobra.Command {
|
||||
var outputTypes []string
|
||||
var folderPath string
|
||||
func newTemplateCmd(folderPath string, save bool) *cobra.Command {
|
||||
var template string
|
||||
cmd := &cobra.Command{
|
||||
Use: "template",
|
||||
@@ -26,6 +25,12 @@ func newTemplateCmd() *cobra.Command {
|
||||
Example: "sail search template",
|
||||
Aliases: []string{"temp"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
folderPath, _ := cmd.Flags().GetString("folderPath")
|
||||
if folderPath == "" {
|
||||
cmd.MarkFlagRequired("save")
|
||||
}
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
err := config.InitConfig()
|
||||
@@ -65,10 +70,10 @@ func newTemplateCmd() *cobra.Command {
|
||||
log.Warn("multiple template matches, the first match will be used", "template", template)
|
||||
}
|
||||
selectedTemplate = matches[0]
|
||||
varCount := len(selectedTemplate.Variables)
|
||||
if varCount > 0 {
|
||||
for i := 0; i < varCount; i++ {
|
||||
varEntry := selectedTemplate.Variables[i]
|
||||
|
||||
if len(selectedTemplate.Variables) > 0 {
|
||||
for _, varEntry := range selectedTemplate.Variables {
|
||||
|
||||
resp := terminal.InputPrompt("Input " + varEntry.Prompt + ":")
|
||||
selectedTemplate.Raw = []byte(strings.ReplaceAll(string(selectedTemplate.Raw), "{{"+varEntry.Name+"}}", resp))
|
||||
}
|
||||
@@ -85,17 +90,17 @@ func newTemplateCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
err = search.IterateIndices(formattedResponse, selectedTemplate.SearchQuery.Query.GetQuery(), folderPath, outputTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
if save {
|
||||
err = search.IterateIndices(formattedResponse, selectedTemplate.SearchQuery.Query.GetQuery(), folderPath, []string{"json"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
cmd.Println(util.PrettyPrint(formattedResponse))
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringArrayVarP(&outputTypes, "output types", "o", []string{"json"}, "the sort value for the api call (examples)")
|
||||
cmd.Flags().StringVarP(&folderPath, "folderPath", "f", "search_results", "folder path to save the search results in. If the directory doesn't exist, then it will be automatically created. (default is the current working directory)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func TestNewTemplateCommand(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
cmd := newTemplateCmd()
|
||||
cmd := newTemplateCmd("", false)
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
cmd.SetOut(b)
|
||||
|
||||
@@ -55,7 +55,7 @@ func newAuthCommand() *cobra.Command {
|
||||
log.Info("Authentication method set to OAuth")
|
||||
|
||||
default:
|
||||
log.Error("Invalid Selection")
|
||||
log.Warn("No selection made")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -11,23 +11,17 @@ import (
|
||||
func newDebugCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "debug",
|
||||
Short: "Set the CLI Debug Mode",
|
||||
Long: "\nSet the CLI Debug Mode, Primarily used for Logging and Troubleshooting\n\n",
|
||||
Short: "Enable or Disable Debug Mode for the CLI",
|
||||
Long: "\nEnable or Disable Debug Mode for the CLI, Primarily used for troubleshooting.\n\n",
|
||||
Example: "sail set debug disable | sail set debug enable | sail set debug true | sail set debug false",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
switch strings.ToLower(args[0]) {
|
||||
case "enable":
|
||||
case "enable", "true":
|
||||
viper.Set("debug", true)
|
||||
log.Info("Debug Enabled")
|
||||
case "true":
|
||||
viper.Set("debug", true)
|
||||
log.Info("Debug Enabled")
|
||||
case "disable":
|
||||
viper.Set("debug", false)
|
||||
log.Info("Debug Disabled")
|
||||
case "false":
|
||||
case "disable", "false":
|
||||
viper.Set("debug", false)
|
||||
log.Info("Debug Disabled")
|
||||
default:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2021, SailPoint Technologies, Inc. All rights reserved.
|
||||
package configure
|
||||
package set
|
||||
|
||||
import (
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
@@ -7,16 +7,15 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewConfigureCmd(term terminal.Terminal) *cobra.Command {
|
||||
func newPATCommand(term terminal.Terminal) *cobra.Command {
|
||||
var ClientID string
|
||||
var ClientSecret string
|
||||
var err error
|
||||
cmd := &cobra.Command{
|
||||
Use: "configure",
|
||||
Short: "Configure PAT Authentication for the currently active environment",
|
||||
Long: "\nConfigure PAT Authentication for the CLI\n\nPrerequisites:\n\nCreate a Client ID and Client Secret\nhttps://developer.sailpoint.com/idn/api/authentication#personal-access-tokens",
|
||||
Aliases: []string{"conf"},
|
||||
Args: cobra.NoArgs,
|
||||
Use: "pat",
|
||||
Short: "Configure PAT Authentication for the currently active environment",
|
||||
Long: "\nConfigure PAT Authentication for the CLI\n\nPrerequisites:\n\nCreate a Client ID and Client Secret\nhttps://developer.sailpoint.com/idn/api/authentication#personal-access-tokens",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if ClientID == "" {
|
||||
@@ -2,12 +2,11 @@
|
||||
package set
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewSetCommand() *cobra.Command {
|
||||
func NewSetCmd(term terminal.Terminal) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "Configure settings for the SailPoint CLI",
|
||||
@@ -15,7 +14,7 @@ func NewSetCommand() *cobra.Command {
|
||||
Example: "sail set",
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -24,6 +23,7 @@ func NewSetCommand() *cobra.Command {
|
||||
newAuthCommand(),
|
||||
newExportTemplateCommand(),
|
||||
newSearchTemplateCommand(),
|
||||
newPATCommand(term),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
||||
@@ -2,21 +2,28 @@
|
||||
package spconfig
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/spconfig"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newDownloadCmd() *cobra.Command {
|
||||
//go:embed download.md
|
||||
var downloadHelp string
|
||||
|
||||
func newDownloadCommand() *cobra.Command {
|
||||
help := util.ParseHelp(downloadHelp)
|
||||
var importIDs []string
|
||||
var exportIDs []string
|
||||
var folderPath string
|
||||
cmd := &cobra.Command{
|
||||
Use: "download",
|
||||
Short: "Download the results of import or export job from IdentityNow",
|
||||
Long: "\nDownload the results of import or export job from IdentityNow\n\n",
|
||||
Example: "sail spconfig download -export <export job id> -import <import job id>",
|
||||
Use: "download {--import <importID> --export <exportID>}",
|
||||
Short: "Download the results of import or export jobs from IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"down"},
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
@@ -26,38 +33,28 @@ func newDownloadCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(importIDs) > 0 {
|
||||
for i := 0; i < len(importIDs); i++ {
|
||||
jobId := importIDs[i]
|
||||
log.Info("Checking Import Job", "JobID", jobId)
|
||||
err := spconfig.DownloadImport(*apiClient, jobId, "spconfig-import-"+jobId+".json", folderPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, jobId := range importIDs {
|
||||
log.Info("Checking Import Job", "JobID", jobId)
|
||||
err := spconfig.DownloadImport(*apiClient, jobId, "spconfig-import-"+jobId+".json", folderPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Info("No Import Job IDs provided")
|
||||
}
|
||||
|
||||
if len(exportIDs) > 0 {
|
||||
for i := 0; i < len(exportIDs); i++ {
|
||||
jobId := exportIDs[i]
|
||||
log.Info("Checking Export Job", "JobID", jobId)
|
||||
err := spconfig.DownloadExport(*apiClient, jobId, "spconfig-export-"+jobId+".json", folderPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, jobId := range exportIDs {
|
||||
log.Info("Checking Export Job", "JobID", jobId)
|
||||
err := spconfig.DownloadExport(*apiClient, jobId, "spconfig-export-"+jobId+".json", folderPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Info("No Export Job IDs provided")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringArrayVarP(&importIDs, "import", "i", []string{}, "specify the IDs of the import jobs to download results for")
|
||||
cmd.Flags().StringArrayVarP(&exportIDs, "export", "e", []string{}, "specify the IDs of the export jobs to download results for")
|
||||
cmd.Flags().StringArrayVarP(&importIDs, "import", "", []string{}, "specify the IDs of the import jobs to download results for")
|
||||
cmd.Flags().StringArrayVarP(&exportIDs, "export", "", []string{}, "specify the IDs of the export jobs to download results for")
|
||||
cmd.Flags().StringVarP(&folderPath, "folderPath", "f", "spconfig-exports", "folder path to save the search results in. If the directory doesn't exist, then it will be automatically created. (default is the current working directory)")
|
||||
|
||||
return cmd
|
||||
|
||||
12
cmd/spconfig/download.md
Normal file
12
cmd/spconfig/download.md
Normal file
@@ -0,0 +1,12 @@
|
||||
==Long==
|
||||
# Download
|
||||
|
||||
Download the results of Import or Export jobs from IdentityNow
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail spconfig download
|
||||
```
|
||||
====
|
||||
@@ -3,41 +3,55 @@ package spconfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
sailpointbetasdk "github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/spconfig"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newExportCmd() *cobra.Command {
|
||||
//go:embed export.md
|
||||
var exportHelp string
|
||||
|
||||
func newExportCommand() *cobra.Command {
|
||||
help := util.ParseHelp(exportHelp)
|
||||
|
||||
var objectOptions string
|
||||
var folderPath string
|
||||
var description string
|
||||
var includeTypes []string
|
||||
var excludeTypes []string
|
||||
var wait bool
|
||||
var payload *sailpointbetasdk.ExportPayload
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "export",
|
||||
Short: "Start an Export job in IdentityNow",
|
||||
Long: "\nStart an Export job in IdentityNow\n\n",
|
||||
Example: "sail spconfig export",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"exp"},
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
var options *map[string]beta.ObjectExportImportOptions
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
payload = sailpointbetasdk.NewExportPayload()
|
||||
payload.Description = &description
|
||||
payload.IncludeTypes = includeTypes
|
||||
payload.ExcludeTypes = excludeTypes
|
||||
if objectOptions != "" {
|
||||
err = json.Unmarshal([]byte(objectOptions), &options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
job, _, err := apiClient.Beta.SPConfigApi.ExportSpConfig(context.TODO()).ExportPayload(*payload).Execute()
|
||||
job, _, err := apiClient.Beta.SPConfigApi.ExportSpConfig(context.TODO()).ExportPayload(beta.ExportPayload{Description: &description, IncludeTypes: includeTypes, ExcludeTypes: excludeTypes, ObjectOptions: options}).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -54,9 +68,10 @@ func newExportCmd() *cobra.Command {
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&folderPath, "folderPath", "f", "spconfig-exports", "folder path to save the search results in. If the directory doesn't exist, then it will be automatically created. (default is the current working directory)")
|
||||
cmd.Flags().StringVarP(&description, "description", "d", "", "optional description for the export job")
|
||||
cmd.Flags().StringVarP(&description, "description", "", "", "optional description for the export job")
|
||||
cmd.Flags().StringArrayVarP(&includeTypes, "include", "i", []string{}, "types to include in export job")
|
||||
cmd.Flags().StringArrayVarP(&excludeTypes, "exclude", "e", []string{}, "types to exclude in export job")
|
||||
cmd.Flags().StringVarP(&objectOptions, "objectOptions", "o", "", "options for the object types being exported")
|
||||
cmd.Flags().BoolVarP(&wait, "wait", "w", false, "wait for the export job to finish, and download the results")
|
||||
|
||||
return cmd
|
||||
|
||||
44
cmd/spconfig/export.md
Normal file
44
cmd/spconfig/export.md
Normal file
@@ -0,0 +1,44 @@
|
||||
==Long==
|
||||
# Export
|
||||
Start an Export job in IdentityNow
|
||||
|
||||
Valid Types that can be included or excluded are:
|
||||
- ACCESS_PROFILE
|
||||
- ACCESS_REQUEST_CONFIG
|
||||
- ATTR_SYNC_SOURCE_CONFIG
|
||||
- AUTH_ORG
|
||||
- CAMPAIGN_FILTER
|
||||
- FORM_DEFINITION
|
||||
- GOVERNANCE_GROUP
|
||||
- IDENTITY_OBJECT_CONFIG
|
||||
- IDENTITY_PROFILE
|
||||
- LIFECYCLE_STATE
|
||||
- NOTIFICATION_TEMPLATE
|
||||
- PASSWORD_POLICY
|
||||
- PASSWORD_SYNC_GROUP
|
||||
- PUBLIC_IDENTITIES_CONFIG
|
||||
- ROLE
|
||||
- RULE
|
||||
- SERVICE_DESK_INTEGRATION
|
||||
- SOD_POLICY
|
||||
- SOURCE
|
||||
- TRANSFORM
|
||||
- TRIGGER_SUBSCRIPTION
|
||||
- WORKFLOWS
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail spconfig export --include WORKFLOWS --include SOURCE
|
||||
sail spconfig export --include SOURCE --wait
|
||||
sail spconfig export --include TRANSFORM --objectOptions '{
|
||||
"TRANSFORM": {
|
||||
"includedIds": [],
|
||||
"includedNames": [
|
||||
"Remove Diacritical Marks",
|
||||
"Common - Location Lookup"
|
||||
]
|
||||
}
|
||||
}'
|
||||
```
|
||||
====
|
||||
@@ -2,29 +2,34 @@
|
||||
package spconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewSPConfigCmd() *cobra.Command {
|
||||
//go:embed spconfig.md
|
||||
var spconfigHelp string
|
||||
|
||||
func NewSPConfigCommand() *cobra.Command {
|
||||
help := util.ParseHelp(spconfigHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "spconfig",
|
||||
Short: "Perform SPConfig operations in IdentityNow",
|
||||
Long: "\nPerform SPConfig operations in IdentityNow\n\n",
|
||||
Example: "sail spconfig",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"spcon"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newExportCmd(),
|
||||
newStatusCmd(),
|
||||
newTemplateCmd(),
|
||||
newDownloadCmd(),
|
||||
newExportCommand(),
|
||||
newStatusCommand(),
|
||||
newTemplateCommand(),
|
||||
newDownloadCommand(),
|
||||
newImportCommand(),
|
||||
)
|
||||
|
||||
|
||||
16
cmd/spconfig/spconfig.md
Normal file
16
cmd/spconfig/spconfig.md
Normal file
@@ -0,0 +1,16 @@
|
||||
==Long==
|
||||
# SPConfig
|
||||
Perform SP-Config operations in IdentityNow
|
||||
|
||||
API References:
|
||||
- https://developer.sailpoint.com/idn/api/beta/sp-config
|
||||
====
|
||||
|
||||
==Example==
|
||||
|
||||
```bash
|
||||
sail spconfig export --include WORKFLOWS --include SOURCE --wait
|
||||
sail spconfig import
|
||||
```
|
||||
|
||||
====
|
||||
@@ -19,7 +19,7 @@ func TestNewSPConfigCommand(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
cmd := NewSPConfigCmd()
|
||||
cmd := NewSPConfigCommand()
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
cmd.SetOut(b)
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newStatusCmd() *cobra.Command {
|
||||
func newStatusCommand() *cobra.Command {
|
||||
var exportJobs []string
|
||||
var importJobs []string
|
||||
cmd := &cobra.Command{
|
||||
@@ -26,20 +26,18 @@ func newStatusCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < len(exportJobs); i++ {
|
||||
job := exportJobs[i]
|
||||
for _, jobId := range exportJobs {
|
||||
|
||||
status, _, err := apiClient.Beta.SPConfigApi.ExportSpConfigJobStatus(context.TODO(), job).Execute() //SPConfigApi.SpConfigExportJobStatus(ctx, job).Execute()
|
||||
status, _, err := apiClient.Beta.SPConfigApi.GetSpConfigExportStatus(context.TODO(), jobId).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spconfig.PrintJob(*status)
|
||||
}
|
||||
|
||||
for i := 0; i < len(importJobs); i++ {
|
||||
job := importJobs[i]
|
||||
for _, jobId := range importJobs {
|
||||
|
||||
status, _, err := apiClient.Beta.SPConfigApi.ImportSpConfigJobStatus(context.TODO(), job).Execute()
|
||||
status, _, err := apiClient.Beta.SPConfigApi.GetSpConfigImportStatus(context.TODO(), jobId).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -50,8 +48,8 @@ func newStatusCmd() *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringArrayVarP(&importJobs, "import", "i", []string{}, "a list of import job ids to return the status of")
|
||||
cmd.Flags().StringArrayVarP(&exportJobs, "export", "e", []string{}, "a list of export job ids to return the status of")
|
||||
cmd.Flags().StringArrayVarP(&importJobs, "import", "", []string{}, "a list of import job ids to return the status of")
|
||||
cmd.Flags().StringArrayVarP(&exportJobs, "export", "", []string{}, "a list of export job ids to return the status of")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package spconfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
@@ -13,19 +14,23 @@ import (
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/templates"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/types"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newTemplateCmd() *cobra.Command {
|
||||
var outputTypes []string
|
||||
//go:embed template.md
|
||||
var templateHelp string
|
||||
|
||||
func newTemplateCommand() *cobra.Command {
|
||||
help := util.ParseHelp(templateHelp)
|
||||
var folderPath string
|
||||
var template string
|
||||
var wait bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "template",
|
||||
Short: "Begin an SPConfig Export task in IdentityNow using a template",
|
||||
Long: "\nBegin an SPConfig Export task in IdentityNow using a template\n\n",
|
||||
Example: "sail spconfig template --wait",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"temp"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
@@ -91,7 +96,6 @@ func newTemplateCmd() *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringArrayVarP(&outputTypes, "outputTypes", "o", []string{"json"}, "the sort value for the api call (examples)")
|
||||
cmd.Flags().StringVarP(&folderPath, "folderPath", "f", "spconfig-exports", "folder path to save the search results in. If the directory doesn't exist, then it will be automatically created. (default is the current working directory)")
|
||||
cmd.Flags().BoolVarP(&wait, "wait", "w", false, "wait for the export job to finish, and download the results")
|
||||
|
||||
|
||||
15
cmd/spconfig/template.md
Normal file
15
cmd/spconfig/template.md
Normal file
@@ -0,0 +1,15 @@
|
||||
==Long==
|
||||
|
||||
# Template
|
||||
|
||||
Begin an SPConfig Export task in IdentityNow using a template
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
|
||||
```bash
|
||||
sail spconfig template --wait
|
||||
```
|
||||
|
||||
====
|
||||
@@ -19,7 +19,7 @@ func TestNewTemplateCommand(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
cmd := newTemplateCmd()
|
||||
cmd := newTemplateCommand()
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
cmd.SetOut(b)
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newCreateCmd() *cobra.Command {
|
||||
func newCreateCommand() *cobra.Command {
|
||||
var filepath string
|
||||
cmd := &cobra.Command{
|
||||
Use: "create",
|
||||
|
||||
@@ -104,7 +104,7 @@ func TestNewCRUDCmd(t *testing.T) {
|
||||
// ctrl := gomock.NewController(t)
|
||||
// defer ctrl.Finish()
|
||||
|
||||
createCMD := newCreateCmd()
|
||||
createCMD := newCreateCommand()
|
||||
|
||||
createBuffer := new(bytes.Buffer)
|
||||
createCMD.SetOut(createBuffer)
|
||||
@@ -134,7 +134,7 @@ func TestNewCRUDCmd(t *testing.T) {
|
||||
t.Fatalf("Unable to save test data: %v", err)
|
||||
}
|
||||
|
||||
cmd := newUpdateCmd()
|
||||
cmd := newUpdateCommand()
|
||||
|
||||
cmd.Flags().Set("file", PATH.Join(path, updateFile))
|
||||
|
||||
@@ -143,7 +143,7 @@ func TestNewCRUDCmd(t *testing.T) {
|
||||
t.Fatalf("error execute cmd: %v", err)
|
||||
}
|
||||
|
||||
deleteCMD := newDeleteCmd()
|
||||
deleteCMD := newDeleteCommand()
|
||||
|
||||
deleteBuffer := new(bytes.Buffer)
|
||||
deleteCMD.SetOut(deleteBuffer)
|
||||
|
||||
@@ -3,92 +3,27 @@ package transform
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/charmbracelet/bubbles/table"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/transform"
|
||||
tuitable "github.com/sailpoint-oss/sailpoint-cli/internal/tui/table"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newDeleteCmd() *cobra.Command {
|
||||
func newDeleteCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Delete an IdentityNow Transform",
|
||||
Long: "\nDelete an IdentityNow Transform\n\n",
|
||||
Example: "sail transform delete 03d5187b-ab96-402c-b5a1-40b74285d77a | sail transform delete",
|
||||
Example: "sail transform delete 03d5187b-ab96-402c-b5a1-40b74285d77a",
|
||||
Aliases: []string{"d"},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var id []string
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
transforms, err := transform.GetTransforms(*apiClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
columns := []table.Column{
|
||||
{Title: "ID", Width: 40},
|
||||
{Title: "Name", Width: 25},
|
||||
{Title: "Type", Width: 25},
|
||||
}
|
||||
|
||||
var rows []table.Row
|
||||
|
||||
for i := 0; i < len(transforms); i++ {
|
||||
transform := transforms[i]
|
||||
rows = append(rows, []string{*transform.Id, transform.Name, transform.Type})
|
||||
}
|
||||
|
||||
t := table.New(
|
||||
table.WithColumns(columns),
|
||||
table.WithRows(rows),
|
||||
table.WithFocused(true),
|
||||
table.WithHeight(7),
|
||||
)
|
||||
|
||||
s := table.DefaultStyles()
|
||||
s.Header = s.Header.
|
||||
BorderStyle(lipgloss.NormalBorder()).
|
||||
BorderForeground(lipgloss.Color("240")).
|
||||
BorderBottom(true).
|
||||
Bold(false)
|
||||
s.Selected = s.Selected.
|
||||
Foreground(lipgloss.Color("229")).
|
||||
Background(lipgloss.Color("57")).
|
||||
Bold(false)
|
||||
t.SetStyles(s)
|
||||
|
||||
m := tuitable.Model{Table: t}
|
||||
if _, err := tea.NewProgram(m).Run(); err != nil {
|
||||
fmt.Println("Error running program:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
tempRow := m.Retrieve()
|
||||
|
||||
if len(tempRow) > 0 {
|
||||
id = append(id, m.Retrieve()[0])
|
||||
} else {
|
||||
return fmt.Errorf("no transform selected")
|
||||
}
|
||||
} else {
|
||||
id = args
|
||||
}
|
||||
|
||||
for i := 0; i < len(id); i++ {
|
||||
|
||||
transformID := id[i]
|
||||
for _, transformID := range args {
|
||||
|
||||
_, err = apiClient.V3.TransformsApi.DeleteTransform(context.TODO(), transformID).Execute()
|
||||
if err != nil {
|
||||
|
||||
@@ -2,18 +2,21 @@
|
||||
package transform
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
sailpoint "github.com/sailpoint-oss/golang-sdk"
|
||||
v3 "github.com/sailpoint-oss/golang-sdk/v3"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/transform"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newDownloadCmd() *cobra.Command {
|
||||
func newDownloadCommand() *cobra.Command {
|
||||
var destination string
|
||||
cmd := &cobra.Command{
|
||||
Use: "download",
|
||||
@@ -29,14 +32,9 @@ func newDownloadCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
transforms, err := transform.GetTransforms(*apiClient)
|
||||
transforms, resp, err := sailpoint.PaginateWithDefaults[v3.Transform](apiClient.V3.TransformsApi.ListTransforms(context.TODO()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = transform.ListTransforms(transforms)
|
||||
if err != nil {
|
||||
return err
|
||||
return sdk.HandleSDKError(resp, err)
|
||||
}
|
||||
|
||||
for _, v := range transforms {
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestNewDownloadCmd(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
cmd := newListCmd()
|
||||
cmd := newListCommand()
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
cmd.SetOut(b)
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
package transform
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sailpoint "github.com/sailpoint-oss/golang-sdk"
|
||||
v3 "github.com/sailpoint-oss/golang-sdk/v3"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/transform"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/output"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newListCmd() *cobra.Command {
|
||||
func newListCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List all Transforms in IdentityNow",
|
||||
@@ -22,15 +27,19 @@ func newListCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
transforms, err := transform.GetTransforms(*apiClient)
|
||||
transforms, resp, err := sailpoint.PaginateWithDefaults[v3.Transform](apiClient.V3.TransformsApi.ListTransforms(context.TODO()))
|
||||
if err != nil {
|
||||
return err
|
||||
return sdk.HandleSDKError(resp, err)
|
||||
}
|
||||
|
||||
err = transform.ListTransforms(transforms)
|
||||
if err != nil {
|
||||
return err
|
||||
var entries [][]string
|
||||
|
||||
for _, v := range transforms {
|
||||
entries = append(entries, []string{v.Name, *v.Id})
|
||||
}
|
||||
|
||||
output.WriteTable(cmd.OutOrStdout(), []string{"Name", "ID"}, entries)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestNewListCmd(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
cmd := newListCmd()
|
||||
cmd := newListCommand()
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
cmd.SetOut(b)
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
|
||||
var implicitInput bool
|
||||
|
||||
func newPreviewCmd() *cobra.Command {
|
||||
func newPreviewCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "preview",
|
||||
Short: "Preview the effects of an IdentityNow Transform",
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
package transform
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -14,7 +12,7 @@ const (
|
||||
userEndpoint = "/cc/api/identity/list"
|
||||
)
|
||||
|
||||
func NewTransformCmd() *cobra.Command {
|
||||
func NewTransformCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "transform",
|
||||
Short: "Manage Transforms in IdentityNow",
|
||||
@@ -22,19 +20,19 @@ func NewTransformCmd() *cobra.Command {
|
||||
Example: "sail transform | sail tran",
|
||||
Aliases: []string{"tran"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringP("transforms-endpoint", "e", transformsEndpoint, "Override transforms endpoint")
|
||||
|
||||
cmd.AddCommand(
|
||||
newListCmd(),
|
||||
newDownloadCmd(),
|
||||
newCreateCmd(),
|
||||
newUpdateCmd(),
|
||||
newDeleteCmd(),
|
||||
newPreviewCmd(),
|
||||
newListCommand(),
|
||||
newDownloadCommand(),
|
||||
newCreateCommand(),
|
||||
newUpdateCommand(),
|
||||
newDeleteCommand(),
|
||||
newPreviewCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newUpdateCmd() *cobra.Command {
|
||||
func newUpdateCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "Update a Transform in IdentityNow from a File",
|
||||
|
||||
@@ -1,41 +1,54 @@
|
||||
package va
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/va"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/vbauerster/mpb/v8"
|
||||
)
|
||||
|
||||
func newCollectCmd(term terminal.Terminal) *cobra.Command {
|
||||
//go:embed collect.md
|
||||
var collectHelp string
|
||||
|
||||
func newCollectCommand(term terminal.Terminal) *cobra.Command {
|
||||
help := util.ParseHelp(collectHelp)
|
||||
var credentials []string
|
||||
var output string
|
||||
var logs bool
|
||||
var config bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "collect",
|
||||
Short: "Collect Configuration or Log Files from a SailPoint Virtual Appliance",
|
||||
Long: "\nCollect Configuration or Log Files from a SailPoint Virtual Appliance\n\n",
|
||||
Example: "sail va collect 10.10.10.25, 10.10.10.26 -p S@ilp0int -p S@ilp0int \n\nLog Files:\n/home/sailpoint/log/ccg.log\n/home/sailpoint/log/charon.log\n/home/sailpoint/stuntlog.txt\n\nConfig Files:\n/home/sailpoint/proxy.yaml\n/etc/systemd/network/static.network\n/etc/resolv.conf\n",
|
||||
Use: "collect [-c | -l] [-o output] VA-Network-Address... [-p va-password]",
|
||||
Short: "Collect files from a SailPoint Virtual Appliance",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var err error
|
||||
|
||||
logFiles := []string{"/home/sailpoint/log/ccg.log", "/home/sailpoint/log/charon.log"}
|
||||
configFiles := []string{"/home/sailpoint/proxy.yaml", "/etc/systemd/network/static.network", "/etc/resolv.conf"}
|
||||
|
||||
if output == "" {
|
||||
output, _ = os.Getwd()
|
||||
}
|
||||
var files []string
|
||||
if logs {
|
||||
files = []string{"/home/sailpoint/log/ccg.log", "/home/sailpoint/log/charon.log", "/home/sailpoint/stuntlog.txt"}
|
||||
} else if config {
|
||||
files = []string{"/home/sailpoint/proxy.yaml", "/etc/systemd/network/static.network", "/etc/resolv.conf"}
|
||||
} else {
|
||||
files = []string{"/home/sailpoint/log/ccg.log", "/home/sailpoint/log/charon.log", "/home/sailpoint/stuntlog.txt", "/home/sailpoint/proxy.yaml", "/etc/systemd/network/static.network", "/etc/resolv.conf"}
|
||||
files = append(files, logFiles...)
|
||||
}
|
||||
if config {
|
||||
files = append(files, configFiles...)
|
||||
}
|
||||
|
||||
if !config && !logs {
|
||||
files = append(files, logFiles...)
|
||||
files = append(files, configFiles...)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
@@ -45,7 +58,12 @@ func newCollectCmd(term terminal.Terminal) *cobra.Command {
|
||||
mpb.WithWaitGroup(&wg))
|
||||
|
||||
for i, endpoint := range args {
|
||||
password := credentials[i]
|
||||
var password string
|
||||
|
||||
if len(credentials) >= i-1 {
|
||||
password = credentials[i]
|
||||
}
|
||||
|
||||
if password == "" {
|
||||
password, err = term.PromptPassword("Please enter the password for " + endpoint)
|
||||
if err != nil {
|
||||
@@ -70,12 +88,12 @@ func newCollectCmd(term terminal.Terminal) *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&output, "Output", "o", "", "The path to save the log files")
|
||||
cmd.Flags().BoolVarP(&logs, "logs", "l", false, "Retrieve log files")
|
||||
cmd.Flags().BoolVarP(&config, "config", "c", false, "Retrieve config files")
|
||||
cmd.Flags().StringArrayVarP(&credentials, "Passwords", "p", []string{}, "You can enter the Passwords for the servers in the same order that the servers are listed as arguments")
|
||||
cmd.Flags().StringVarP(&output, "output", "o", "", "The path to save the log files")
|
||||
cmd.Flags().BoolVarP(&logs, "log", "l", false, "retrieve log files")
|
||||
cmd.Flags().BoolVarP(&config, "config", "c", false, "retrieve config files")
|
||||
cmd.Flags().StringArrayVarP(&credentials, "passwords", "p", []string{}, "passwords for the servers in the same order that the servers are listed as arguments")
|
||||
|
||||
cmd.MarkFlagsMutuallyExclusive("config", "logs")
|
||||
cmd.MarkFlagsMutuallyExclusive("config", "log")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
30
cmd/va/collect.md
Normal file
30
cmd/va/collect.md
Normal file
@@ -0,0 +1,30 @@
|
||||
==Long==
|
||||
# Collect
|
||||
|
||||
Collect files from a remote Virtual Appliance
|
||||
|
||||
Files are collected over SFTP. Passwords are provided via the --password (-p) flag or they will be prompted for at runtime. Server addresses can be DNS names or IP addresses, and are provided as arguments separated by spaces.
|
||||
|
||||
Log Files:
|
||||
```bash
|
||||
/home/sailpoint/log/ccg.log
|
||||
/home/sailpoint/log/charon.log
|
||||
```
|
||||
|
||||
Config Files:
|
||||
```bash
|
||||
/home/sailpoint/proxy.yaml
|
||||
/etc/systemd/network/static.network
|
||||
/etc/resolv.conf
|
||||
```
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail va collect 10.10.10.25 10.10.10.26 -p S@ilp0int -p S@ilp0int
|
||||
sail va collect 10.10.10.25 --config
|
||||
sail va collect 10.10.10.26 --log
|
||||
sail va collect 10.10.10.25 --log --output log_files
|
||||
sail va collect 10.10.10.25 --output all_files
|
||||
```
|
||||
====
|
||||
69
cmd/va/get.go
Normal file
69
cmd/va/get.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package va
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
sailpoint "github.com/sailpoint-oss/golang-sdk"
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
//go:embed get.md
|
||||
var getHelp string
|
||||
|
||||
func newGetCommand() *cobra.Command {
|
||||
help := util.ParseHelp(getHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get a Virtual Appliance configuration from IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ClientIDs []string
|
||||
var VAs []beta.ManagedClientStatus
|
||||
|
||||
clusters, resp, clustersErr := sailpoint.PaginateWithDefaults[beta.ManagedCluster](apiClient.Beta.ManagedClustersApi.GetManagedClusters(context.TODO()))
|
||||
if clustersErr != nil {
|
||||
return sdk.HandleSDKError(resp, clustersErr)
|
||||
}
|
||||
|
||||
for _, cluster := range clusters {
|
||||
for _, id := range cluster.ClientIds {
|
||||
if len(args) > 0 {
|
||||
if slices.Contains(args, id) {
|
||||
ClientIDs = append(ClientIDs, id)
|
||||
|
||||
}
|
||||
} else {
|
||||
ClientIDs = append(ClientIDs, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range ClientIDs {
|
||||
clientStatus, resp, clientErr := apiClient.Beta.ManagedClientsApi.GetManagedClientStatus(context.TODO(), id).Type_("VA").Execute()
|
||||
if clientErr != nil {
|
||||
return sdk.HandleSDKError(resp, clientErr)
|
||||
}
|
||||
VAs = append(VAs, *clientStatus)
|
||||
}
|
||||
|
||||
cmd.Println(util.PrettyPrint(VAs))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
13
cmd/va/get.md
Normal file
13
cmd/va/get.md
Normal file
@@ -0,0 +1,13 @@
|
||||
==Long==
|
||||
|
||||
# Get
|
||||
|
||||
Get a Virtual Appliance configuration from IdentityNow
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail va get
|
||||
```
|
||||
====
|
||||
@@ -2,21 +2,27 @@ package va
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
sailpoint "github.com/sailpoint-oss/golang-sdk"
|
||||
sailpointbetasdk "github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/output"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newListCmd() *cobra.Command {
|
||||
//go:embed list.md
|
||||
var listHelp string
|
||||
|
||||
func newListCommand() *cobra.Command {
|
||||
help := util.ParseHelp(listHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List the Clusters and Virtual Appliances configured in IdentityNow",
|
||||
Long: "\nList the Clusters and Virtual Appliances configured in IdentityNow\n\n",
|
||||
Example: "sail va list",
|
||||
Short: "List the Virtual Appliances configured in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
@@ -25,12 +31,27 @@ func newListCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
clusters, resp, err := sailpoint.PaginateWithDefaults[sailpointbetasdk.ManagedCluster](apiClient.Beta.ManagedClustersApi.GetManagedClusters(context.TODO()))
|
||||
if err != nil {
|
||||
return sdk.HandleSDKError(resp, err)
|
||||
clusters, resp, clustersErr := sailpoint.PaginateWithDefaults[beta.ManagedCluster](apiClient.Beta.ManagedClustersApi.GetManagedClusters(context.TODO()))
|
||||
if clustersErr != nil {
|
||||
return sdk.HandleSDKError(resp, clustersErr)
|
||||
}
|
||||
|
||||
cmd.Println(util.PrettyPrint(clusters))
|
||||
var clients [][]string
|
||||
|
||||
for _, cluster := range clusters {
|
||||
for _, id := range cluster.ClientIds {
|
||||
clientStatus, resp, clientErr := apiClient.Beta.ManagedClientsApi.GetManagedClientStatus(context.TODO(), id).Type_("VA").Execute()
|
||||
if clientErr != nil {
|
||||
return sdk.HandleSDKError(resp, clientErr)
|
||||
}
|
||||
|
||||
if clientStatus.Status != "NOT_CONFIGURED" {
|
||||
clients = append(clients, []string{*cluster.Name, clientStatus.Body["internal_ip"].(string), clientStatus.Body["id"].(string)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output.WriteTable(cmd.OutOrStdout(), []string{"Cluster", "IP Address", "ID"}, clients)
|
||||
|
||||
return nil
|
||||
},
|
||||
|
||||
13
cmd/va/list.md
Normal file
13
cmd/va/list.md
Normal file
@@ -0,0 +1,13 @@
|
||||
==Long==
|
||||
|
||||
# List
|
||||
|
||||
List the Clusters and Virtual Appliances in the configured IdentityNow tenant
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail va list
|
||||
```
|
||||
====
|
||||
@@ -3,6 +3,7 @@ package va
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/vbauerster/mpb/v8"
|
||||
"github.com/vbauerster/mpb/v8/decor"
|
||||
@@ -174,7 +176,7 @@ func ErrorCheck(token []byte) bool {
|
||||
return bytes.Contains(token, errorString) || bytes.Contains(token, exceptionString)
|
||||
}
|
||||
|
||||
func ParseCCGFile(p *mpb.Progress, filepath string, everything bool) error {
|
||||
func ParseCCGFile(p *mpb.Progress, filepath string, all bool) error {
|
||||
file, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -230,7 +232,7 @@ func ParseCCGFile(p *mpb.Progress, filepath string, everything bool) error {
|
||||
if err != nil {
|
||||
break
|
||||
} else {
|
||||
if ErrorCheck(token) || everything {
|
||||
if ErrorCheck(token) || all {
|
||||
var line CCG
|
||||
unErr := json.Unmarshal(token, &line)
|
||||
if unErr == nil && line.Org != "" {
|
||||
@@ -250,7 +252,7 @@ func ParseCCGFile(p *mpb.Progress, filepath string, everything bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ParseCanalFile(p *mpb.Progress, filepath string, everything bool) error {
|
||||
func ParseCanalFile(p *mpb.Progress, filepath string, all bool) error {
|
||||
file, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -318,18 +320,23 @@ func ParseCanalFile(p *mpb.Progress, filepath string, everything bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newParseCmd() *cobra.Command {
|
||||
var ccg bool
|
||||
var canal bool
|
||||
var everything bool
|
||||
//go:embed parse.md
|
||||
var parseHelp string
|
||||
|
||||
func newParseCommand() *cobra.Command {
|
||||
help := util.ParseHelp(parseHelp)
|
||||
var fileType string
|
||||
var all bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "parse",
|
||||
Short: "Parse Log Files from SailPoint Virtual Appliances",
|
||||
Long: "\nParse Log Files from SailPoint Virtual Appliances\n\n",
|
||||
Example: "sail va parse ./path/to/ccg.log ./path/to/ccg.log ./path/to/canal.log ./path/to/canal.log",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if ccg || canal {
|
||||
|
||||
if fileType != "" {
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
p := mpb.New(
|
||||
@@ -341,43 +348,41 @@ func newParseCmd() *cobra.Command {
|
||||
log.Info("Parsing Log Files", "files", args)
|
||||
|
||||
log.SetOutput(p)
|
||||
for i := 0; i < len(args); i++ {
|
||||
for _, filepath := range args {
|
||||
wg.Add(1)
|
||||
|
||||
filepath := args[i]
|
||||
|
||||
if ccg {
|
||||
go func() {
|
||||
switch fileType {
|
||||
case "ccg":
|
||||
go func(filepath string) {
|
||||
defer wg.Done()
|
||||
err := ParseCCGFile(p, filepath, everything)
|
||||
err := ParseCCGFile(p, filepath, all)
|
||||
if err != nil {
|
||||
log.Error("Issue Parsing log file", "file", filepath, "error", err)
|
||||
}
|
||||
}()
|
||||
} else if canal {
|
||||
go func() {
|
||||
}(filepath)
|
||||
case "canal":
|
||||
go func(filepath string) {
|
||||
defer wg.Done()
|
||||
err := ParseCanalFile(p, filepath, everything)
|
||||
err := ParseCanalFile(p, filepath, all)
|
||||
if err != nil {
|
||||
log.Error("Issue Parsing log file", "file", filepath, "error", err)
|
||||
}
|
||||
}()
|
||||
}(filepath)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
} else {
|
||||
return errors.New("must specify either ccg or canal")
|
||||
cmd.Help()
|
||||
}
|
||||
return nil
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&ccg, "ccg", "", false, "Specifies the provided files are CCG Files")
|
||||
cmd.Flags().BoolVarP(&canal, "canal", "", false, "Specifies the provided files are CANAL Files")
|
||||
cmd.Flags().BoolVarP(&everything, "everything", "e", false, "Specifies all log traffic should be parsed, not just errors")
|
||||
cmd.MarkFlagsMutuallyExclusive("ccg", "canal")
|
||||
cmd.MarkFlagsMutuallyExclusive("everything", "canal")
|
||||
cmd.Flags().StringVarP(&fileType, "type", "t", "", "Specifies the log type to parse (ccg, canal)")
|
||||
cmd.Flags().BoolVarP(&all, "all", "a", false, "Specifies all log traffic should be parsed, not just errors")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
25
cmd/va/parse.md
Normal file
25
cmd/va/parse.md
Normal file
@@ -0,0 +1,25 @@
|
||||
==Long==
|
||||
# Parse
|
||||
|
||||
Parse Log Files from SailPoint Virtual Appliances
|
||||
====
|
||||
|
||||
==Example==
|
||||
|
||||
## Parsing CCG Logs:
|
||||
|
||||
All the errors will be parsed out of the log file and sorted by date and connector name.
|
||||
|
||||
Supplying the `--all` flag will parse all the log traffic out, not just errors.
|
||||
|
||||
```bash
|
||||
sail va parse --type ccg ./path/to/ccg.log ./path/to/ccg.log
|
||||
sail va parse --type ccg ./path/to/ccg.log ./path/to/ccg.log --all
|
||||
```
|
||||
|
||||
## Parsing CANAL Logs:
|
||||
|
||||
```bash
|
||||
sail va parse --type canal ./path/to/canal.log ./path/to/canal.log
|
||||
```
|
||||
====
|
||||
@@ -36,8 +36,7 @@ func NewTroubleshootCmd(term terminal.Terminal) *cobra.Command {
|
||||
credentials = append(credentials, password)
|
||||
}
|
||||
|
||||
for host := 0; host < len(args); host++ {
|
||||
endpoint := args[host]
|
||||
for index, endpoint := range args {
|
||||
outputDir := path.Join(output, endpoint)
|
||||
|
||||
if _, err := os.Stat(outputDir); errors.Is(err, os.ErrNotExist) {
|
||||
@@ -47,16 +46,13 @@ func NewTroubleshootCmd(term terminal.Terminal) *cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
password := credentials[host]
|
||||
password := credentials[index]
|
||||
|
||||
orgErr := va.RunVACmdLive(endpoint, password, TroubleshootingScript)
|
||||
if orgErr != nil {
|
||||
return orgErr
|
||||
}
|
||||
|
||||
color.Green("Troubleshooting Complete")
|
||||
color.Blue("Collecting stuntlog")
|
||||
|
||||
var wg sync.WaitGroup
|
||||
p := mpb.New(mpb.WithWidth(60),
|
||||
mpb.PopCompletedMode(),
|
||||
|
||||
0
cmd/va/troubleshoot.md
Normal file
0
cmd/va/troubleshoot.md
Normal file
@@ -19,7 +19,7 @@ func updateAndRebootVA(endpoint, password string) {
|
||||
log.Info("Virtual Appliance Updating", "VA", endpoint)
|
||||
reboot, rebootErr := va.RunVACmd(endpoint, password, RebootCommand)
|
||||
if rebootErr != nil && rebootErr.Error() != "wait: remote command exited without exit status or exit signal" {
|
||||
log.Error("Problem Rebooting", "VA", endpoint, "err", rebootErr, "resp", reboot)
|
||||
log.Error("Problem Rebooting", "Server", endpoint, "err", rebootErr, "resp", reboot)
|
||||
} else {
|
||||
log.Info("Virtual Appliance Rebooting", "VA", endpoint)
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func updateAndRebootVA(endpoint, password string) {
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func newUpdateCmd(term terminal.Terminal) *cobra.Command {
|
||||
func newUpdateCommand(term terminal.Terminal) *cobra.Command {
|
||||
var credentials []string
|
||||
cmd := &cobra.Command{
|
||||
Use: "update",
|
||||
|
||||
11
cmd/va/update.md
Normal file
11
cmd/va/update.md
Normal file
@@ -0,0 +1,11 @@
|
||||
==Long==
|
||||
# Update
|
||||
|
||||
Update a SailPoint Virtual Appliance
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail va update 10.10.10.25
|
||||
```
|
||||
====
|
||||
30
cmd/va/va.go
30
cmd/va/va.go
@@ -2,31 +2,35 @@
|
||||
package va
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/va/logConfig"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewVACmd(term terminal.Terminal) *cobra.Command {
|
||||
//go:embed va.md
|
||||
var vaHelp string
|
||||
|
||||
func NewVACommand(term terminal.Terminal) *cobra.Command {
|
||||
help := util.ParseHelp(vaHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "va",
|
||||
Short: "Interact with SailPoint Virtual Appliances",
|
||||
Long: "\nInteract with SailPoint Virtual Appliances\n\n",
|
||||
Aliases: []string{"va"},
|
||||
Short: "Manage SailPoint Virtual Appliances",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newCollectCmd(term),
|
||||
// newTroubleshootCmd(),
|
||||
newListCmd(),
|
||||
newParseCmd(),
|
||||
newUpdateCmd(term),
|
||||
logConfig.NewLogCmd(),
|
||||
newCollectCommand(term),
|
||||
// newTroubleshootCommand(),
|
||||
newGetCommand(),
|
||||
newParseCommand(),
|
||||
newUpdateCommand(term),
|
||||
newListCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
||||
14
cmd/va/va.md
Normal file
14
cmd/va/va.md
Normal file
@@ -0,0 +1,14 @@
|
||||
==Long==
|
||||
# VA
|
||||
|
||||
Manage Virtual Appliances in IdentityNow
|
||||
|
||||
====
|
||||
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail va collect 10.10.10.25
|
||||
sail va list
|
||||
```
|
||||
====
|
||||
121
cmd/workflow/create.go
Normal file
121
cmd/workflow/create.go
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package workflow
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed create.md
|
||||
var createHelp string
|
||||
|
||||
func newCreateCommand() *cobra.Command {
|
||||
help := util.ParseHelp(createHelp)
|
||||
var file bool
|
||||
var directory bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "create [-f file1 file2 ... | -d workflowDirectory ]",
|
||||
Short: "Create Workflows in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"cr"},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var workflows []beta.Workflow
|
||||
var returnedWorkflows []beta.Workflow
|
||||
var workflowFiles []string
|
||||
|
||||
if directory {
|
||||
for _, workflowDirectory := range args {
|
||||
files, err := os.ReadDir(workflowDirectory)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
if !file.IsDir() && strings.Contains(file.Name(), ".json") {
|
||||
workflowFiles = append(workflowFiles, file.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if file {
|
||||
|
||||
workflowFiles = args
|
||||
|
||||
} else {
|
||||
cmd.Help()
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, filePath := range workflowFiles {
|
||||
|
||||
file, err := os.OpenFile(filePath, os.O_RDONLY, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(file)
|
||||
decoder.DisallowUnknownFields()
|
||||
|
||||
var workflow beta.Workflow
|
||||
err = decoder.Decode(&workflow)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workflows = append(workflows, workflow)
|
||||
|
||||
}
|
||||
|
||||
for _, workflow := range workflows {
|
||||
body, err := workflow.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createReq := beta.CreateWorkflowRequest{}
|
||||
|
||||
err = createReq.UnmarshalJSON(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workflowResp, resp, sdkErr := apiClient.Beta.WorkflowsApi.CreateWorkflow(context.TODO()).CreateWorkflowRequest(createReq).Execute()
|
||||
if sdkErr != nil {
|
||||
err := sdk.HandleSDKError(resp, sdkErr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
returnedWorkflows = append(returnedWorkflows, *workflowResp)
|
||||
}
|
||||
|
||||
cmd.Println(util.PrettyPrint(returnedWorkflows))
|
||||
|
||||
return nil
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&file, "file", "f", false, "specifies that workflow file paths are provided as arguments to be created")
|
||||
cmd.Flags().BoolVarP(&directory, "directory", "d", false, "specifies that a directory of workflows is provided to be created")
|
||||
cmd.MarkFlagsMutuallyExclusive("file", "directory")
|
||||
|
||||
return cmd
|
||||
|
||||
}
|
||||
25
cmd/workflow/create.md
Normal file
25
cmd/workflow/create.md
Normal file
@@ -0,0 +1,25 @@
|
||||
==Long==
|
||||
# Create
|
||||
Create Workflows in IdentityNow
|
||||
|
||||
## API References:
|
||||
- https://developer.sailpoint.com/idn/api/beta/create-workflow
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
## File Paths:
|
||||
**Note:** File paths are relative to the current working directory, and only one workflow is allowed per file path. Multiple Workflows can be provided by specifying multiple file paths as arguments.
|
||||
|
||||
```bash
|
||||
sail workflow create -f {file-path}
|
||||
sail workflow create -f {file-path} {file-path} ...
|
||||
```
|
||||
|
||||
## Folder Paths:
|
||||
```bash
|
||||
sail workflow create -d {folder-path}
|
||||
sail workflow create -d {folder-path} {folder-path} ...
|
||||
```
|
||||
|
||||
====
|
||||
65
cmd/workflow/delete.go
Normal file
65
cmd/workflow/delete.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package workflow
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed delete.md
|
||||
var deleteHelp string
|
||||
|
||||
func newDeleteCommand() *cobra.Command {
|
||||
help := util.ParseHelp(deleteHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete workflowID... ",
|
||||
Short: "Delete a Workflow in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"del"},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
|
||||
for _, id := range args {
|
||||
|
||||
resp, sdkErr := apiClient.Beta.WorkflowsApi.DeleteWorkflow(context.TODO(), id).Execute()
|
||||
if sdkErr != nil {
|
||||
err := sdk.HandleSDKError(resp, sdkErr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if resp.StatusCode == 204 {
|
||||
log.Info("Workflow deleted", "id", id)
|
||||
} else {
|
||||
log.Warn("Workflow delete failed", "id", id)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
cmd.Help()
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
||||
}
|
||||
17
cmd/workflow/delete.md
Normal file
17
cmd/workflow/delete.md
Normal file
@@ -0,0 +1,17 @@
|
||||
==Long==
|
||||
# Delete
|
||||
Delete a workflow in IdentityNow
|
||||
|
||||
## API References:
|
||||
- https://developer.sailpoint.com/idn/api/beta/delete-workflow
|
||||
====
|
||||
|
||||
==Example==
|
||||
|
||||
## Arguments:
|
||||
```bash
|
||||
sail workflow delete id1
|
||||
sail workflow delete id1 id2 ...
|
||||
sail workflow del $(cat list_of_workflowIDs.txt)
|
||||
```
|
||||
====
|
||||
82
cmd/workflow/download.go
Normal file
82
cmd/workflow/download.go
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package workflow
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
clean "github.com/mrz1836/go-sanitize"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed download.md
|
||||
var downloadHelp string
|
||||
|
||||
func newDownloadCommand() *cobra.Command {
|
||||
help := util.ParseHelp(downloadHelp)
|
||||
var folderPath string
|
||||
cmd := &cobra.Command{
|
||||
Use: "download",
|
||||
Short: "Download Workflows from IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"down"},
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workflows, resp, sdkErr := apiClient.Beta.WorkflowsApi.ListWorkflows(context.TODO()).Execute()
|
||||
if sdkErr != nil {
|
||||
err := sdk.HandleSDKError(resp, sdkErr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range workflows {
|
||||
fileName := clean.PathName(*v.Name) + ".json"
|
||||
|
||||
fullPath := path.Join(folderPath, fileName)
|
||||
|
||||
err := os.MkdirAll(folderPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.WriteString(util.PrettyPrint(v))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = file.Sync()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&folderPath, "folder", "f", "workflows", "Folder to save the Workflows to")
|
||||
|
||||
return cmd
|
||||
|
||||
}
|
||||
17
cmd/workflow/download.md
Normal file
17
cmd/workflow/download.md
Normal file
@@ -0,0 +1,17 @@
|
||||
==Long==
|
||||
# Download
|
||||
Downloads all Workflows from IdentityNow
|
||||
|
||||
## API References:
|
||||
- https://developer.sailpoint.com/idn/api/beta/list-workflows
|
||||
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
|
||||
```bash
|
||||
sail workflow download
|
||||
sail workflow download -f my-workflows
|
||||
```
|
||||
====
|
||||
61
cmd/workflow/get.go
Normal file
61
cmd/workflow/get.go
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package workflow
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
//go:embed get.md
|
||||
var getHelp string
|
||||
|
||||
func newGetCommand() *cobra.Command {
|
||||
help := util.ParseHelp(getHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get Workflows in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"g"},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workflows, resp, sdkErr := apiClient.Beta.WorkflowsApi.ListWorkflows(context.TODO()).Execute()
|
||||
if sdkErr != nil {
|
||||
err := sdk.HandleSDKError(resp, sdkErr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
var filteredList []beta.Workflow
|
||||
for _, workflow := range workflows {
|
||||
if slices.Contains(args, *workflow.Id) {
|
||||
filteredList = append(filteredList, workflow)
|
||||
|
||||
}
|
||||
}
|
||||
workflows = filteredList
|
||||
}
|
||||
|
||||
cmd.Println(util.PrettyPrint(workflows))
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
||||
}
|
||||
17
cmd/workflow/get.md
Normal file
17
cmd/workflow/get.md
Normal file
@@ -0,0 +1,17 @@
|
||||
==Long==
|
||||
|
||||
# Get
|
||||
|
||||
Get workflows from IdentityNow.
|
||||
|
||||
## API References
|
||||
- https://developer.sailpoint.com/idn/api/beta/list-workflows
|
||||
====
|
||||
|
||||
==Example==
|
||||
|
||||
```bash
|
||||
sail workflow get
|
||||
sail workflow get f691874a-c5a5-426d-9dd4-33129072bafa
|
||||
```
|
||||
====
|
||||
55
cmd/workflow/list.go
Normal file
55
cmd/workflow/list.go
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package workflow
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/output"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed list.md
|
||||
var listHelp string
|
||||
|
||||
func newListCommand() *cobra.Command {
|
||||
help := util.ParseHelp(listHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List all Workflows in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"ls"},
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workflows, resp, sdkErr := apiClient.Beta.WorkflowsApi.ListWorkflows(context.TODO()).Execute()
|
||||
if sdkErr != nil {
|
||||
err := sdk.HandleSDKError(resp, sdkErr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var tableList [][]string
|
||||
for _, entry := range workflows {
|
||||
tableList = append(tableList, []string{*entry.Name, *entry.Id})
|
||||
}
|
||||
|
||||
output.WriteTable(cmd.OutOrStdout(), []string{"Name", "ID"}, tableList)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
||||
}
|
||||
16
cmd/workflow/list.md
Normal file
16
cmd/workflow/list.md
Normal file
@@ -0,0 +1,16 @@
|
||||
==Long==
|
||||
|
||||
# List
|
||||
|
||||
List workflows from IdentityNow.
|
||||
|
||||
## API References
|
||||
- https://developer.sailpoint.com/idn/api/beta/list-workflows
|
||||
====
|
||||
|
||||
==Example==
|
||||
|
||||
```bash
|
||||
sail Workflow list
|
||||
```
|
||||
====
|
||||
102
cmd/workflow/update.go
Normal file
102
cmd/workflow/update.go
Normal file
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package workflow
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed update.md
|
||||
var updateHelp string
|
||||
|
||||
func newUpdateCommand() *cobra.Command {
|
||||
help := util.ParseHelp(updateHelp)
|
||||
var file bool
|
||||
var directory bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "Update a Workflow in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"up"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
var workflowFiles []string
|
||||
var workflowList []beta.Workflow
|
||||
|
||||
apiClient, err := config.InitAPIClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if directory {
|
||||
for _, workflowDirectory := range args {
|
||||
files, err := os.ReadDir(workflowDirectory)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
if !file.IsDir() && strings.Contains(file.Name(), ".json") {
|
||||
workflowFiles = append(workflowFiles, file.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if file {
|
||||
workflowFiles = args
|
||||
} else {
|
||||
cmd.Help()
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, workflowFile := range workflowFiles {
|
||||
var workflow beta.Workflow
|
||||
contents, err := os.ReadFile(workflowFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
workflow.UnmarshalJSON(contents)
|
||||
workflowList = append(workflowList, workflow)
|
||||
}
|
||||
|
||||
for _, workflowEntry := range workflowList {
|
||||
|
||||
body, err := workflowEntry.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workFlowBody := beta.WorkflowBody{}
|
||||
workFlowBody.UnmarshalJSON(body)
|
||||
|
||||
returnedWorkflow, resp, sdkErr := apiClient.Beta.WorkflowsApi.UpdateWorkflow(context.TODO(), *workflowEntry.Id).WorkflowBody(workFlowBody).Execute()
|
||||
if sdkErr != nil {
|
||||
err := sdk.HandleSDKError(resp, sdkErr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cmd.Println(util.PrettyPrint(returnedWorkflow))
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&file, "file", "f", false, "Read workflow from file(s)")
|
||||
cmd.Flags().BoolVarP(&directory, "directory", "d", false, "Read workflow from stdin")
|
||||
cmd.MarkFlagsMutuallyExclusive("file", "directory")
|
||||
|
||||
return cmd
|
||||
|
||||
}
|
||||
23
cmd/workflow/update.md
Normal file
23
cmd/workflow/update.md
Normal file
@@ -0,0 +1,23 @@
|
||||
==Long==
|
||||
# Update
|
||||
|
||||
Update a Workflow in IdentityNow
|
||||
|
||||
Arguments can be a list of directories or files.
|
||||
If a directory is specified, all JSON files in the directory will be parsed and the workflows uploaded.
|
||||
|
||||
## API References:
|
||||
- https://developer.sailpoint.com/idn/api/beta/update-workflow
|
||||
====
|
||||
|
||||
==Example==
|
||||
## File:
|
||||
```bash
|
||||
sail Workflow update -f {file-path} {file-path}
|
||||
```
|
||||
|
||||
## Directory:
|
||||
```bash
|
||||
sail Workflow update -d {folder-path} {folder-path}
|
||||
```
|
||||
====
|
||||
37
cmd/workflow/workflow.go
Normal file
37
cmd/workflow/workflow.go
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2023, SailPoint Technologies, Inc. All rights reserved.
|
||||
package workflow
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
//go:embed workflow.md
|
||||
var workflowHelp string
|
||||
|
||||
func NewWorkflowCommand() *cobra.Command {
|
||||
help := util.ParseHelp(workflowHelp)
|
||||
cmd := &cobra.Command{
|
||||
Use: "workflow",
|
||||
Short: "Manage Workflows in IdentityNow",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Aliases: []string{"work"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newListCommand(),
|
||||
newDownloadCommand(),
|
||||
newCreateCommand(),
|
||||
newUpdateCommand(),
|
||||
newDeleteCommand(),
|
||||
newGetCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
15
cmd/workflow/workflow.md
Normal file
15
cmd/workflow/workflow.md
Normal file
@@ -0,0 +1,15 @@
|
||||
==Long==
|
||||
|
||||
# Workflows
|
||||
|
||||
Manage Workflows in IdentityNow
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
```bash
|
||||
sail workflow list
|
||||
sail workflow download
|
||||
sail workflow update -f ./workflow-file.json
|
||||
```
|
||||
====
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user