mirror of
https://github.com/LukeHagar/sailpoint-cli.git
synced 2025-12-06 04:21:15 +00:00
Help > Usage, Naming, Markdown Help, Spelling, File name Sanitization
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,6 +6,7 @@ transform_files
|
||||
search_results
|
||||
spconfig-exports
|
||||
reports
|
||||
workflows
|
||||
|
||||
# CLI binary
|
||||
sailpoint-cli
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewReportCmd() *cobra.Command {
|
||||
func NewReportCommand() *cobra.Command {
|
||||
var save bool
|
||||
var folderPath string
|
||||
var template string
|
||||
@@ -70,10 +70,10 @@ func NewReportCmd() *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))
|
||||
}
|
||||
@@ -83,9 +83,7 @@ func NewReportCmd() *cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(selectedTemplate.Queries); i++ {
|
||||
|
||||
currentQuery := selectedTemplate.Queries[i]
|
||||
for i, currentQuery := range selectedTemplate.Queries {
|
||||
|
||||
searchQuery := v3.NewSearch()
|
||||
query := v3.NewQuery()
|
||||
@@ -100,11 +98,6 @@ func NewReportCmd() *cobra.Command {
|
||||
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)
|
||||
// }
|
||||
|
||||
if save {
|
||||
fileName := selectedTemplate.Name + ".json"
|
||||
err := output.SaveJSONFile(selectedTemplate.Queries, fileName, folderPath)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
package root
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/connector"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/environment"
|
||||
@@ -13,18 +13,26 @@ import (
|
||||
"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/internal/config"
|
||||
"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{
|
||||
@@ -33,17 +41,7 @@ func NewRootCmd() *cobra.Command {
|
||||
DisableDescriptions: true,
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var tempEnv string
|
||||
if env != "" {
|
||||
tempEnv = config.GetActiveEnvironment()
|
||||
config.SetActiveEnvironment(env)
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
|
||||
if tempEnv != "" {
|
||||
config.SetActiveEnvironment(tempEnv)
|
||||
}
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -51,17 +49,21 @@ func NewRootCmd() *cobra.Command {
|
||||
|
||||
root.AddCommand(
|
||||
set.NewSetCmd(t),
|
||||
environment.NewEnvironmentCmd(),
|
||||
environment.NewEnvironmentCommand(),
|
||||
connector.NewConnCmd(t),
|
||||
transform.NewTransformCmd(),
|
||||
va.NewVACmd(t),
|
||||
search.NewSearchCmd(),
|
||||
spconfig.NewSPConfigCmd(),
|
||||
report.NewReportCmd(),
|
||||
sdk.NewSDKCmd(),
|
||||
transform.NewTransformCommand(),
|
||||
va.NewVACommand(t),
|
||||
search.NewSearchCommand(),
|
||||
spconfig.NewSPConfigCommand(),
|
||||
report.NewReportCommand(),
|
||||
sdk.NewSDKCommand(),
|
||||
workflow.NewWorkflowCommand(),
|
||||
)
|
||||
|
||||
root.PersistentFlags().StringVar(&env, "env", "", "Environment to use for SailPoint CLI commands")
|
||||
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 search template
|
||||
```
|
||||
====
|
||||
@@ -19,7 +19,7 @@ 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)
|
||||
}
|
||||
@@ -47,7 +47,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)
|
||||
|
||||
@@ -24,7 +24,7 @@ func (c Config) printEnv() {
|
||||
fmt.Println("CLIENT_SECRT=" + c.ClientSecret)
|
||||
}
|
||||
|
||||
func newConfigCmd() *cobra.Command {
|
||||
func newConfigCommand() *cobra.Command {
|
||||
var env bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "config",
|
||||
|
||||
@@ -13,7 +13,7 @@ var goTemplateContents embed.FS
|
||||
|
||||
const goTemplateDirName = "golang"
|
||||
|
||||
func newGolangCmd() *cobra.Command {
|
||||
func newGolangCommand() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "golang",
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newInitCmd() *cobra.Command {
|
||||
func newInitCommand() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "init",
|
||||
@@ -17,15 +15,15 @@ func newInitCmd() *cobra.Command {
|
||||
Aliases: []string{"temp"},
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newTypescriptCmd(),
|
||||
newGolangCmd(),
|
||||
newPowerShellCmd(),
|
||||
newConfigCmd(),
|
||||
newTypescriptCommand(),
|
||||
newGolangCommand(),
|
||||
newPowerShellCommand(),
|
||||
newConfigCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
||||
@@ -13,7 +13,7 @@ var pwshTemplateContents embed.FS
|
||||
|
||||
const pwshTemplateDirName = "powershell"
|
||||
|
||||
func newPowerShellCmd() *cobra.Command {
|
||||
func newPowerShellCommand() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "powershell",
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewSDKCmd() *cobra.Command {
|
||||
func NewSDKCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "sdk",
|
||||
Short: "Initialize or configure SDK projects",
|
||||
@@ -15,12 +13,12 @@ func NewSDKCmd() *cobra.Command {
|
||||
Example: "sail sdk",
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
newInitCmd(),
|
||||
newInitCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
||||
@@ -13,7 +13,7 @@ var tsTemplateContents embed.FS
|
||||
|
||||
const tsTemplateDirName = "typescript"
|
||||
|
||||
func newTypescriptCmd() *cobra.Command {
|
||||
func newTypescriptCommand() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "typescript",
|
||||
|
||||
@@ -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 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,12 +2,12 @@
|
||||
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",
|
||||
@@ -16,15 +16,18 @@ func NewSearchCmd() *cobra.Command {
|
||||
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 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
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
package set
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/terminal"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -16,7 +14,7 @@ func NewSetCmd(term terminal.Terminal) *cobra.Command {
|
||||
Example: "sail set",
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_, _ = fmt.Fprint(cmd.OutOrStdout(), cmd.UsageString())
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -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]
|
||||
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]
|
||||
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)
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newDeleteCmd() *cobra.Command {
|
||||
func newDeleteCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Delete an IdentityNow Transform",
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newDownloadCmd() *cobra.Command {
|
||||
func newDownloadCommand() *cobra.Command {
|
||||
var destination string
|
||||
cmd := &cobra.Command{
|
||||
Use: "download",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newListCmd() *cobra.Command {
|
||||
func newListCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List all Transforms in IdentityNow",
|
||||
|
||||
@@ -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
|
||||
@@ -75,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
|
||||
```
|
||||
====
|
||||
@@ -1,22 +1,27 @@
|
||||
package va
|
||||
package list
|
||||
|
||||
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/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",
|
||||
Long: help.Long,
|
||||
Example: help.Example,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
@@ -25,7 +30,7 @@ func newListCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
clusters, resp, err := sailpoint.PaginateWithDefaults[sailpointbetasdk.ManagedCluster](apiClient.Beta.ManagedClustersApi.GetManagedClusters(context.TODO()))
|
||||
clusters, resp, err := sailpoint.PaginateWithDefaults[beta.ManagedCluster](apiClient.Beta.ManagedClustersApi.GetManagedClusters(context.TODO()))
|
||||
if err != nil {
|
||||
return sdk.HandleSDKError(resp, err)
|
||||
}
|
||||
13
cmd/va/list/list.md
Normal file
13
cmd/va/list/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
|
||||
```
|
||||
====
|
||||
@@ -2,6 +2,7 @@ package logConfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/golang-sdk/beta"
|
||||
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
|
||||
@@ -10,12 +11,16 @@ import (
|
||||
"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 {
|
||||
|
||||
@@ -26,9 +31,7 @@ func newGetCmd() *cobra.Command {
|
||||
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 {
|
||||
|
||||
9
cmd/va/logConfig/get.md
Normal file
9
cmd/va/logConfig/get.md
Normal file
@@ -0,0 +1,9 @@
|
||||
==Long==
|
||||
# Get
|
||||
|
||||
Get a Virtual Appliances clusters log configuration
|
||||
====
|
||||
|
||||
==Example==
|
||||
sail va log get
|
||||
====
|
||||
@@ -2,25 +2,23 @@
|
||||
package logConfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewLogCmd() *cobra.Command {
|
||||
func NewLogCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "log",
|
||||
Short: "Interact with a SailPoint Virtual Appliances log configuration",
|
||||
Long: "\nInteract with SailPoint Virtual Appliances log configuration\n\n",
|
||||
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
|
||||
|
||||
0
cmd/va/logConfig/logConfig.md
Normal file
0
cmd/va/logConfig/logConfig.md
Normal file
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newSetCmd() *cobra.Command {
|
||||
func newSetCommand() *cobra.Command {
|
||||
var level string
|
||||
var durationInMinutes int32
|
||||
var connectors []string
|
||||
@@ -27,7 +27,7 @@ func newSetCmd() *cobra.Command {
|
||||
|
||||
rootLevel := beta.StandardLevel(level)
|
||||
|
||||
if rootLevel.IsValid() == false {
|
||||
if !rootLevel.IsValid() {
|
||||
log.Fatal("logLevel provided is invalid", "level", level)
|
||||
}
|
||||
|
||||
@@ -57,9 +57,7 @@ func newSetCmd() *cobra.Command {
|
||||
logConfig := beta.NewClientLogConfiguration(durationInMinutes, rootLevel)
|
||||
logConfig.LogLevels = &logLevels
|
||||
|
||||
for i := 0; i < len(args); i++ {
|
||||
|
||||
clusterId := args[i]
|
||||
for _, clusterId := range args {
|
||||
|
||||
configuration, resp, err := apiClient.Beta.ManagedClustersApi.PutClientLogConfiguration(context.TODO(), clusterId).ClientLogConfiguration(*logConfig).Execute()
|
||||
if err != nil {
|
||||
|
||||
0
cmd/va/logConfig/set.md
Normal file
0
cmd/va/logConfig/set.md
Normal file
@@ -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,15 +320,19 @@ func ParseCanalFile(p *mpb.Progress, filepath string, everything bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newParseCmd() *cobra.Command {
|
||||
//go:embed parse.md
|
||||
var parseHelp string
|
||||
|
||||
func newParseCommand() *cobra.Command {
|
||||
help := util.ParseHelp(parseHelp)
|
||||
var ccg bool
|
||||
var canal bool
|
||||
var everything bool
|
||||
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 {
|
||||
@@ -341,27 +347,25 @@ 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() {
|
||||
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)
|
||||
}
|
||||
}()
|
||||
}(filepath)
|
||||
} else if canal {
|
||||
go func() {
|
||||
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()
|
||||
@@ -375,9 +379,9 @@ func newParseCmd() *cobra.Command {
|
||||
|
||||
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.Flags().BoolVarP(&all, "all", "a", false, "Specifies all log traffic should be parsed, not just errors")
|
||||
cmd.MarkFlagsMutuallyExclusive("ccg", "canal")
|
||||
cmd.MarkFlagsMutuallyExclusive("everything", "canal")
|
||||
cmd.MarkFlagsMutuallyExclusive("all", "canal")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
17
cmd/va/parse.md
Normal file
17
cmd/va/parse.md
Normal file
@@ -0,0 +1,17 @@
|
||||
==Long==
|
||||
# Parse
|
||||
|
||||
Parse Log Files from SailPoint Virtual Appliances
|
||||
|
||||
|
||||
|
||||
====
|
||||
|
||||
==Example==
|
||||
|
||||
```bash
|
||||
sail va parse --ccg ./path/to/ccg.log ./path/to/ccg.log
|
||||
sail va parse --canal ./path/to/canal.log ./path/to/canal.log
|
||||
```
|
||||
|
||||
====
|
||||
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",
|
||||
|
||||
0
cmd/va/update.md
Normal file
0
cmd/va/update.md
Normal file
30
cmd/va/va.go
30
cmd/va/va.go
@@ -2,31 +2,37 @@
|
||||
package va
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "embed"
|
||||
|
||||
"github.com/sailpoint-oss/sailpoint-cli/cmd/va/list"
|
||||
"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 Virtual Appliances in IdentityNow",
|
||||
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(),
|
||||
newParseCommand(),
|
||||
newUpdateCommand(term),
|
||||
list.NewListCommand(),
|
||||
logConfig.NewLogCommand(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
||||
16
cmd/va/va.md
Normal file
16
cmd/va/va.md
Normal file
@@ -0,0 +1,16 @@
|
||||
==Long==
|
||||
|
||||
# VA
|
||||
|
||||
Manage Virtual Appliances in IdentityNow
|
||||
|
||||
====
|
||||
|
||||
|
||||
==Example==
|
||||
|
||||
```bash
|
||||
sail va
|
||||
```
|
||||
|
||||
====
|
||||
57
go.mod
57
go.mod
@@ -3,28 +3,29 @@ module github.com/sailpoint-oss/sailpoint-cli
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/charmbracelet/bubbles v0.15.0
|
||||
github.com/charmbracelet/bubbletea v0.24.0
|
||||
github.com/charmbracelet/bubbles v0.16.1
|
||||
github.com/charmbracelet/bubbletea v0.24.2
|
||||
github.com/charmbracelet/glamour v0.6.0
|
||||
github.com/charmbracelet/lipgloss v0.7.1
|
||||
github.com/charmbracelet/log v0.2.1
|
||||
github.com/charmbracelet/log v0.2.2
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/gocarina/gocsv v0.0.0-20230513223533-9ddd7fd60602
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/kr/pretty v0.3.1
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/mrz1836/go-sanitize v1.3.0
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/pkg/sftp v1.13.5
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.5
|
||||
github.com/sailpoint-oss/golang-sdk v1.1.6
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.15.0
|
||||
github.com/vbauerster/mpb/v8 v8.4.0
|
||||
golang.org/x/crypto v0.9.0
|
||||
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc
|
||||
golang.org/x/oauth2 v0.8.0
|
||||
golang.org/x/term v0.8.0
|
||||
github.com/spf13/viper v1.16.0
|
||||
github.com/vbauerster/mpb/v8 v8.5.2
|
||||
github.com/zalando/go-keyring v0.2.3
|
||||
golang.org/x/crypto v0.11.0
|
||||
golang.org/x/oauth2 v0.10.0
|
||||
golang.org/x/term v0.10.0
|
||||
gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61
|
||||
gopkg.in/square/go-jose.v2 v2.6.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
@@ -32,21 +33,26 @@ require (
|
||||
|
||||
require (
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.4 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
|
||||
github.com/alessio/shellescape v1.4.1 // indirect
|
||||
github.com/alecthomas/chroma v0.10.0 // indirect
|
||||
github.com/alessio/shellescape v1.4.2 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/danieljoos/wincred v1.2.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
@@ -54,28 +60,31 @@ require (
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.25 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.15.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
|
||||
github.com/muesli/termenv v0.15.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sahilm/fuzzy v0.1.0 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/zalando/go-keyring v0.2.3 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
github.com/yuin/goldmark v1.5.5 // indirect
|
||||
github.com/yuin/goldmark-emoji v1.0.2 // indirect
|
||||
golang.org/x/net v0.12.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
golang.org/x/text v0.11.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
153
go.sum
153
go.sum
@@ -42,28 +42,28 @@ github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1o
|
||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
||||
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
|
||||
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=
|
||||
github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
|
||||
github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0=
|
||||
github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
|
||||
github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/charmbracelet/bubbles v0.15.0 h1:c5vZ3woHV5W2b8YZI1q7v4ZNQaPetfHuoHzx+56Z6TI=
|
||||
github.com/charmbracelet/bubbles v0.15.0/go.mod h1:Y7gSFbBzlMpUDR/XM9MhZI374Q+1p1kluf1uLl8iK74=
|
||||
github.com/charmbracelet/bubbletea v0.23.1/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU=
|
||||
github.com/charmbracelet/bubbletea v0.23.2 h1:vuUJ9HJ7b/COy4I30e8xDVQ+VRDUEFykIjryPfgsdps=
|
||||
github.com/charmbracelet/bubbletea v0.23.2/go.mod h1:FaP3WUivcTM0xOKNmhciz60M6I+weYLF76mr1JyI7sM=
|
||||
github.com/charmbracelet/bubbletea v0.24.0 h1:l8PHrft/GIeikDPCUhQe53AJrDD8xGSn0Agirh8xbe8=
|
||||
github.com/charmbracelet/bubbletea v0.24.0/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg=
|
||||
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
|
||||
github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk=
|
||||
github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY=
|
||||
github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc=
|
||||
github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY=
|
||||
github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg=
|
||||
github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc=
|
||||
github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc=
|
||||
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
|
||||
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
|
||||
github.com/charmbracelet/log v0.2.1 h1:1z7jpkk4yKyjwlmKmKMM5qnEDSpV32E7XtWhuv0mTZE=
|
||||
github.com/charmbracelet/log v0.2.1/go.mod h1:GwFfjewhcVDWLrpAbY5A0Hin9YOlEn40eWT4PNaxFT4=
|
||||
github.com/charmbracelet/log v0.2.2 h1:CaXgos+ikGn5tcws5Cw3paQuk9e/8bIwuYGhnkqQFjo=
|
||||
github.com/charmbracelet/log v0.2.2/go.mod h1:Zs11hKpb8l+UyX4y1srwZIGW+MPCXJHIty3MB9l/sno=
|
||||
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=
|
||||
@@ -71,10 +71,9 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
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/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE=
|
||||
@@ -82,6 +81,9 @@ github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0S
|
||||
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/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
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=
|
||||
@@ -90,7 +92,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
@@ -99,10 +100,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027 h1:LCGzZb4kMUUjMUzLxxqSJBwo9szUO0tK8cOxnEOT4Jc=
|
||||
github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
|
||||
github.com/gocarina/gocsv v0.0.0-20230513223533-9ddd7fd60602 h1:HSpPf+lPYwzoJNup34uegmOQk5Qm83S+wpu8anTDJkg=
|
||||
github.com/gocarina/gocsv v0.0.0-20230513223533-9ddd7fd60602/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -166,12 +163,14 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
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/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
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/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.4/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=
|
||||
@@ -193,7 +192,6 @@ 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/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
@@ -202,39 +200,36 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM=
|
||||
github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
|
||||
github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
|
||||
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/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||
github.com/mrz1836/go-sanitize v1.3.0 h1:ExJE6BCn1YWdopt1NPyMTfxDdTMxOMs8WsJ2GrfN1zo=
|
||||
github.com/mrz1836/go-sanitize v1.3.0/go.mod h1:oakqgm7YGr+k591N0m8FVx7cOywaHr95FWmI4cDYkIc=
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
|
||||
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
|
||||
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
||||
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||
github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
|
||||
github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc=
|
||||
github.com/muesli/termenv v0.14.0/go.mod h1:kG/pF1E7fh949Xhe156crRUrHNyK221IuGO7Ez60Uc8=
|
||||
github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs=
|
||||
github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ=
|
||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us=
|
||||
github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
@@ -249,23 +244,18 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
|
||||
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.3 h1:uJzKJ2+gOdVY7sbpjpvm4O4c3woAjBSx9ASMYi3bh8E=
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.3/go.mod h1:k8tO4zw0wmivf5NjrPE2tF+ToCr6AJUV9BJnyGW4/rA=
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.4 h1:NLdExj3bb7NWKhHnzReP0ZiSUNR+Nlqd58HjHJtue+I=
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.4/go.mod h1:k8tO4zw0wmivf5NjrPE2tF+ToCr6AJUV9BJnyGW4/rA=
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.5 h1:eu0JGrpfzgWDXrdSXkY2sjs0vZ+2iGRN7zcntEDAE7U=
|
||||
github.com/sailpoint-oss/golang-sdk v1.0.5/go.mod h1:k8tO4zw0wmivf5NjrPE2tF+ToCr6AJUV9BJnyGW4/rA=
|
||||
github.com/sailpoint-oss/golang-sdk v1.1.6 h1:5EZkxVDeJXl2ZZDfhnc/mgRPExCzBi1oOJSakcdItlM=
|
||||
github.com/sailpoint-oss/golang-sdk v1.1.6/go.mod h1:llHaEhgszkfXiImwiwwe50WpRQm4xhFXqt19mnmcbk0=
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
|
||||
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
@@ -274,10 +264,11 @@ github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmq
|
||||
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/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
|
||||
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
|
||||
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 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
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=
|
||||
@@ -285,17 +276,24 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
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/vbauerster/mpb/v8 v8.4.0 h1:Jq2iNA7T6SydpMVOwaT+2OBWlXS9Th8KEvBqeu5eeTo=
|
||||
github.com/vbauerster/mpb/v8 v8.4.0/go.mod h1:vjp3hSTuCtR+x98/+2vW3eZ8XzxvGoP8CPseHMhiPyc=
|
||||
github.com/vbauerster/mpb/v8 v8.5.2 h1:zanzt1cZpSEG5uGNYKcv43+97f0IgEnXpuBFaMxKbM0=
|
||||
github.com/vbauerster/mpb/v8 v8.5.2/go.mod h1:YqKyR4ZR6Gd34yD3cDHPMmQxc+uUQMwjgO/LkxiJQ6I=
|
||||
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=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.5.5 h1:IJznPe8wOzfIKETmMkd06F8nXkmlhaHqFRM9l1hAGsU=
|
||||
github.com/yuin/goldmark v1.5.5/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ=
|
||||
github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s=
|
||||
github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY=
|
||||
github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97yms=
|
||||
github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
@@ -312,8 +310,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
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=
|
||||
@@ -324,10 +322,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
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/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
|
||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU=
|
||||
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
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=
|
||||
@@ -385,8 +379,9 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
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=
|
||||
@@ -396,8 +391,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
||||
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.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
|
||||
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
|
||||
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
||||
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
||||
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=
|
||||
@@ -409,10 +404,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
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/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
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=
|
||||
@@ -444,26 +437,24 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
|
||||
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
|
||||
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=
|
||||
@@ -472,8 +463,8 @@ 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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
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=
|
||||
@@ -620,8 +611,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61 h1:8ajkpB4hXVftY5ko905id+dOnmorcS2CHNxxHLLDcFM=
|
||||
gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61/go.mod h1:IfMagxm39Ys4ybJrDb7W3Ob8RwxftP0Yy+or/NVz1O8=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -50,7 +50,7 @@ type CLIConfig struct {
|
||||
ActiveEnvironment string `mapstructure:"activeenvironment"`
|
||||
Environments map[string]Environment `mapstructure:"environments"`
|
||||
|
||||
//Pipline Variables
|
||||
//Pipeline Variables
|
||||
ClientID string `mapstructure:"clientid, omitempty"`
|
||||
ClientSecret string `mapstructure:"clientsecret, omitempty"`
|
||||
BaseURL string `mapstructure:"base_url, omitempty"`
|
||||
|
||||
@@ -5,57 +5,45 @@ import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/gocarina/gocsv"
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/mrz1836/go-sanitize"
|
||||
)
|
||||
|
||||
func SaveJSONFile[T any](formattedResponse T, fileName string, folderPath string) error {
|
||||
savePath := GetSanitizedPath(folderPath, fileName)
|
||||
savePath := GetSanitizedPath(folderPath, fileName, "json")
|
||||
|
||||
log.Debug("Saving JSON file", "file path", savePath)
|
||||
|
||||
dataToSave, err := json.MarshalIndent(formattedResponse, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Make sure the output dir exists first
|
||||
err = os.MkdirAll(folderPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debug("Formatted Data", "data", string(dataToSave))
|
||||
|
||||
file, err := os.OpenFile(savePath, os.O_CREATE|os.O_RDWR, 0777)
|
||||
return WriteFile(savePath, dataToSave)
|
||||
}
|
||||
|
||||
func WriteFile(path string, data []byte) error {
|
||||
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fileWriter := bufio.NewWriter(file)
|
||||
|
||||
_, err = fileWriter.Write(dataToSave)
|
||||
_, err = fileWriter.Write(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SaveCSVFile[T any](formattedResponse T, fileName string, folderPath string) error {
|
||||
savePath := GetSanitizedPath(folderPath, fileName)
|
||||
|
||||
// Make sure the output dir exists first
|
||||
err := os.MkdirAll(folderPath, os.ModePerm)
|
||||
err = fileWriter.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(savePath, os.O_CREATE|os.O_RDWR, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
err = gocsv.MarshalFile(formattedResponse, file)
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -64,7 +52,6 @@ func SaveCSVFile[T any](formattedResponse T, fileName string, folderPath string)
|
||||
}
|
||||
|
||||
// GetSanitizedPath makes sure the provided path works on all OS
|
||||
func GetSanitizedPath(filePath string, fileName string) string {
|
||||
p := path.Join(filePath, fileName)
|
||||
return strings.ReplaceAll(p, ":", " ")
|
||||
func GetSanitizedPath(filePath string, fileName string, extension string) string {
|
||||
return path.Join(filePath, sanitize.PathName(fileName)+"."+extension)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
@@ -26,7 +26,7 @@ type SDKResp struct {
|
||||
func HandleSDKError(resp *http.Response, sdkErr error) error {
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
@@ -43,8 +43,8 @@ func HandleSDKError(resp *http.Response, sdkErr error) error {
|
||||
for _, v := range formattedBody.Messages {
|
||||
outputErr = outputErr + fmt.Sprintf("%s\n", v.Text)
|
||||
}
|
||||
} else {
|
||||
|
||||
} else if len(body) > 0 {
|
||||
outputErr = outputErr + fmt.Sprintf("%s\n", string(body))
|
||||
}
|
||||
|
||||
return errors.New(outputErr)
|
||||
|
||||
@@ -26,8 +26,9 @@ func ParseIndices(indices string) (sailpointsdk.Index, error) {
|
||||
return sailpointsdk.INDEX_IDENTITIES, nil
|
||||
case "roles":
|
||||
return sailpointsdk.INDEX_ROLES, nil
|
||||
}
|
||||
default:
|
||||
return "*", fmt.Errorf("index provided is invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func BuildSearch(searchQuery string, sort []string, indices []string) (sailpointsdk.Search, error) {
|
||||
@@ -120,45 +121,44 @@ func PerformSearch(apiClient sailpoint.APIClient, search sailpointsdk.Search) (S
|
||||
}
|
||||
|
||||
func IterateIndices(SearchResults SearchResults, searchQuery string, folderPath string, outputTypes []string) error {
|
||||
var err error
|
||||
if len(SearchResults.AccountActivities) > 0 {
|
||||
fileName := "query=" + searchQuery + "&indices=AccountActivities"
|
||||
err = SaveResults(SearchResults.AccountActivities, fileName, folderPath, outputTypes)
|
||||
err := SaveResults(SearchResults.AccountActivities, fileName, folderPath, outputTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(SearchResults.AccessProfiles) > 0 {
|
||||
fileName := "query=" + searchQuery + "&indices=AccessProfiles"
|
||||
err = SaveResults(SearchResults.AccessProfiles, fileName, folderPath, outputTypes)
|
||||
err := SaveResults(SearchResults.AccessProfiles, fileName, folderPath, outputTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(SearchResults.Entitlements) > 0 {
|
||||
fileName := "query=" + searchQuery + "&indices=Entitlements"
|
||||
err = SaveResults(SearchResults.Entitlements, fileName, folderPath, outputTypes)
|
||||
err := SaveResults(SearchResults.Entitlements, fileName, folderPath, outputTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(SearchResults.Events) > 0 {
|
||||
fileName := "query=" + searchQuery + "&indices=Events"
|
||||
err = SaveResults(SearchResults.Events, fileName, folderPath, outputTypes)
|
||||
err := SaveResults(SearchResults.Events, fileName, folderPath, outputTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(SearchResults.Identities) > 0 {
|
||||
fileName := "query=" + searchQuery + "&indices=Identities"
|
||||
err = SaveResults(SearchResults.Identities, fileName, folderPath, outputTypes)
|
||||
err := SaveResults(SearchResults.Identities, fileName, folderPath, outputTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(SearchResults.Roles) > 0 {
|
||||
fileName := "query=" + searchQuery + "&indices=Roles"
|
||||
err = SaveResults(SearchResults.Roles, fileName, folderPath, outputTypes)
|
||||
err := SaveResults(SearchResults.Roles, fileName, folderPath, outputTypes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -171,21 +171,12 @@ func SaveResults[T any](formattedResponse []T, fileName string, filePath string,
|
||||
outputType := outputTypes[i]
|
||||
switch outputType {
|
||||
case "json":
|
||||
fileName = fileName + ".json"
|
||||
savePath := output.GetSanitizedPath(filePath, fileName)
|
||||
savePath := output.GetSanitizedPath(filePath, fileName, "json")
|
||||
log.Info("Saving Results", "file", savePath)
|
||||
err := output.SaveJSONFile(formattedResponse, fileName, filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "csv":
|
||||
fileName = fileName + ".csv"
|
||||
savePath := output.GetSanitizedPath(filePath, fileName)
|
||||
log.Info("Saving Results", "file", savePath)
|
||||
err := output.SaveCSVFile(formattedResponse, fileName, filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid output type provided %s", outputType)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func PrintJob(job sailpointbetasdk.SpConfigJob) {
|
||||
func DownloadExport(apiClient sailpoint.APIClient, jobId string, fileName string, folderPath string) error {
|
||||
|
||||
for {
|
||||
response, _, err := apiClient.Beta.SPConfigApi.ExportSpConfigJobStatus(context.TODO(), jobId).Execute()
|
||||
response, _, err := apiClient.Beta.SPConfigApi.GetSpConfigExportStatus(context.TODO(), jobId).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func DownloadExport(apiClient sailpoint.APIClient, jobId string, fileName string
|
||||
switch response.Status {
|
||||
case "COMPLETE":
|
||||
log.Info("Job Complete")
|
||||
exportData, _, err := apiClient.Beta.SPConfigApi.ExportSpConfigDownload(context.TODO(), jobId).Execute()
|
||||
exportData, _, err := apiClient.Beta.SPConfigApi.GetSpConfigExport(context.TODO(), jobId).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func DownloadExport(apiClient sailpoint.APIClient, jobId string, fileName string
|
||||
func DownloadImport(apiClient sailpoint.APIClient, jobId string, fileName string, folderPath string) error {
|
||||
|
||||
for {
|
||||
response, _, err := apiClient.Beta.SPConfigApi.ImportSpConfigJobStatus(context.TODO(), jobId).Execute()
|
||||
response, _, err := apiClient.Beta.SPConfigApi.GetSpConfigImportStatus(context.TODO(), jobId).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func DownloadImport(apiClient sailpoint.APIClient, jobId string, fileName string
|
||||
switch response.Status {
|
||||
case "COMPLETE":
|
||||
color.Green("Downloading Import Data")
|
||||
importData, _, err := apiClient.Beta.SPConfigApi.ImportSpConfigDownload(context.TODO(), jobId).Execute()
|
||||
importData, _, err := apiClient.Beta.SPConfigApi.GetSpConfigImport(context.TODO(), jobId).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,13 +2,71 @@ package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/glamour"
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/mrz1836/go-sanitize"
|
||||
)
|
||||
|
||||
var renderer *glamour.TermRenderer
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
renderer, err = glamour.NewTermRenderer(
|
||||
// detect background color and pick either the default dark or light theme
|
||||
glamour.WithAutoStyle(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func PrettyPrint(v interface{}) string {
|
||||
b, err := json.MarshalIndent(v, "", " ")
|
||||
if err != nil {
|
||||
fmt.Println("error:", err)
|
||||
log.Error("Error marshalling interface", "error", err)
|
||||
}
|
||||
return (string(b))
|
||||
}
|
||||
|
||||
func SanitizeFileName(fileName string) string {
|
||||
return sanitize.PathName(fileName)
|
||||
}
|
||||
|
||||
func RenderMarkdown(markdown string) string {
|
||||
out, err := renderer.Render(markdown)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
type Help struct {
|
||||
Long string
|
||||
Example string
|
||||
}
|
||||
|
||||
func ParseHelp(help string) Help {
|
||||
helpParser, err := regexp.Compile(`==([A-Za-z]+)==([\s\S]*?)====`)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
matches := helpParser.FindAllStringSubmatch(help, -1)
|
||||
|
||||
var helpObj Help
|
||||
for _, set := range matches {
|
||||
switch strings.ToLower(set[1]) {
|
||||
case "long":
|
||||
helpObj.Long = RenderMarkdown(set[2])
|
||||
case "example":
|
||||
helpObj.Example = RenderMarkdown(set[2])
|
||||
}
|
||||
}
|
||||
|
||||
return helpObj
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user