Rewrote Error handlers, Added more help, adjusted functionality

This commit is contained in:
luke-hagar-sp
2023-08-08 11:24:00 -05:00
parent 9fa8ccbf96
commit 67f86c3e3e
16 changed files with 116 additions and 82 deletions

View File

@@ -30,12 +30,20 @@ func NewListCommand() *cobra.Command {
return err
}
clusters, resp, err := sailpoint.PaginateWithDefaults[beta.ManagedCluster](apiClient.Beta.ManagedClustersApi.GetManagedClusters(context.TODO()))
if err != nil {
return sdk.HandleSDKError(resp, err)
clusters, resp, clustersErr := sailpoint.PaginateWithDefaults[beta.ManagedCluster](apiClient.Beta.ManagedClustersApi.GetManagedClusters(context.TODO()))
if clustersErr != nil {
return sdk.HandleSDKError(resp, clustersErr)
}
cmd.Println(util.PrettyPrint(clusters))
for _, cluster := range clusters {
for _, id := range cluster.ClientIds {
clientStatus, resp, clientErr := apiClient.Beta.ManagedClientsApi.GetManagedClientStatus(context.TODO(), id).Type_("VA").Execute()
if clientErr != nil {
return sdk.HandleSDKError(resp, clientErr)
}
cmd.Println(util.PrettyPrint(clientStatus))
}
}
return nil
},

View File

@@ -4,7 +4,6 @@ import (
"context"
_ "embed"
"github.com/sailpoint-oss/golang-sdk/beta"
"github.com/sailpoint-oss/sailpoint-cli/internal/config"
"github.com/sailpoint-oss/sailpoint-cli/internal/sdk"
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
@@ -24,8 +23,6 @@ func newGetCommand() *cobra.Command {
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var output []beta.ClientLogConfiguration
apiClient, err := config.InitAPIClient()
if err != nil {
return err
@@ -38,14 +35,9 @@ func newGetCommand() *cobra.Command {
return sdk.HandleSDKError(resp, err)
}
if configuration != nil {
output = append(output, *configuration)
cmd.Println(util.PrettyPrint(configuration))
}
}
cmd.Println(util.PrettyPrint(output))
return nil
},
}

View File

@@ -5,5 +5,7 @@ Get a Virtual Appliances clusters log configuration
====
==Example==
sail va log get
```bash
sail va log get 2c91808580f6cc1a01811af8cf5f18cb
```
====

View File

@@ -2,6 +2,8 @@ package logConfig
import (
"context"
_ "embed"
"errors"
"strings"
"github.com/charmbracelet/log"
@@ -12,7 +14,11 @@ import (
"github.com/spf13/cobra"
)
//go:embed set.md
var setHelp string
func newSetCommand() *cobra.Command {
help := util.ParseHelp(setHelp)
var level string
var durationInMinutes int32
var connectors []string
@@ -20,31 +26,30 @@ func newSetCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "set",
Short: "Set a Virtual Appliances log configuration",
Long: "\nSet a Virtual Appliances log configuration\n\nA list of Connectors can be found here:\nhttps://community.sailpoint.com/t5/IdentityNow-Articles/Enabling-Connector-Logging-in-IdentityNow/ta-p/188107\n\n",
Example: "sail va log set",
Long: help.Long,
Example: help.Example,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
rootLevel := beta.StandardLevel(level)
if !rootLevel.IsValid() {
log.Fatal("logLevel provided is invalid", "level", level)
return errors.New("invalid logLevel: " + level)
}
if durationInMinutes < 5 || durationInMinutes > 1440 {
log.Fatal("durationInMinutes provided is invalid", "durationInMinutes", durationInMinutes)
return errors.New("invalid durationInMinutes: " + string(durationInMinutes))
}
var output []beta.ClientLogConfiguration
apiClient, err := config.InitAPIClient()
if err != nil {
return err
}
logLevels := make(map[string]beta.StandardLevel)
for j := 0; j < len(connectors); j++ {
connector := connectors[j]
for _, connector := range connectors {
parts := strings.Split(connector, "=")
conLevel := beta.StandardLevel(parts[1])
if conLevel.IsValid() {
@@ -54,21 +59,16 @@ func newSetCommand() *cobra.Command {
}
}
logConfig := beta.NewClientLogConfiguration(durationInMinutes, rootLevel)
logConfig.LogLevels = &logLevels
for _, clusterId := range args {
configuration, resp, err := apiClient.Beta.ManagedClustersApi.PutClientLogConfiguration(context.TODO(), clusterId).ClientLogConfiguration(*logConfig).Execute()
configuration, resp, err := apiClient.Beta.ManagedClustersApi.PutClientLogConfiguration(context.TODO(), clusterId).ClientLogConfiguration(beta.ClientLogConfiguration{DurationMinutes: durationInMinutes, RootLevel: rootLevel, LogLevels: &logLevels}).Execute()
if err != nil {
return sdk.HandleSDKError(resp, err)
}
output = append(output, *configuration)
cmd.Println(util.PrettyPrint(configuration))
}
cmd.Println(util.PrettyPrint(output))
return nil
},
}

View File

@@ -0,0 +1,13 @@
==Long==
# Set
Set a Virtual Appliances clusters log configuration
A list of Connectors (can be found here)[https://community.sailpoint.com/t5/IdentityNow-Articles/Enabling-Connector-Logging-in-IdentityNow/ta-p/188107]
====
==Example==
```bash
sail va log set 2c91808580f6cc1a01811af8cf5f18cb
```
====

View File

@@ -2,16 +2,11 @@
# 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
```
====

View File

@@ -53,9 +53,6 @@ func NewTroubleshootCmd(term terminal.Terminal) *cobra.Command {
return orgErr
}
color.Green("Troubleshooting Complete")
color.Blue("Collecting stuntlog")
var wg sync.WaitGroup
p := mpb.New(mpb.WithWidth(60),
mpb.PopCompletedMode(),

View File

@@ -0,0 +1,11 @@
==Long==
# Update
Update a SailPoint Virtual Appliance
====
==Example==
```bash
sail va update 10.10.10.25
```
====

View File

@@ -1,5 +1,4 @@
==Long==
# VA
Manage Virtual Appliances in IdentityNow
@@ -8,9 +7,8 @@ Manage Virtual Appliances in IdentityNow
==Example==
```bash
sail va
sail va collect 10.10.10.25
sail va list
```
====

View File

@@ -2,10 +2,22 @@
# Update
Update a Workflow in IdentityNow
Arguments can be a list of directories or files.
If a directory is specified, all JSON files in the directory will be parsed and the workflows uploaded.
## API References:
- https://developer.sailpoint.com/idn/api/beta/update-workflow
====
==Example==
## File:
```bash
sail Workflow update
sail Workflow update -f {file-path} {file-path}
```
## Directory:
```bash
sail Workflow update -d {folder-path} {folder-path}
```
====

View File

@@ -10,6 +10,6 @@ Manage Workflows in IdentityNow
```bash
sail workflow list
sail workflow download
sail workflow update -f
sail workflow update -f ./workflow-file.json
```
====

14
go.mod
View File

@@ -7,7 +7,7 @@ require (
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.2
github.com/charmbracelet/log v0.2.3
github.com/fatih/color v1.15.0
github.com/golang/mock v1.6.0
github.com/kr/pretty v0.3.1
@@ -23,9 +23,9 @@ require (
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
golang.org/x/crypto v0.12.0
golang.org/x/oauth2 v0.11.0
golang.org/x/term v0.11.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
@@ -79,10 +79,10 @@ require (
github.com/subosito/gotenv v1.4.2 // 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/net v0.14.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
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect

15
go.sum
View File

@@ -64,6 +64,8 @@ github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZ
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
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/charmbracelet/log v0.2.3 h1:YVmBhJtpGL7nW/nlf5u+SEloU8XYljxozGzZpgwIvhs=
github.com/charmbracelet/log v0.2.3/go.mod h1:ZApwwzDbbETVTIRTk7724yQRJAXIktt98yGVMMaa3y8=
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=
@@ -228,6 +230,7 @@ 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.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=
@@ -312,6 +315,8 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
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=
@@ -382,6 +387,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
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/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
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=
@@ -393,6 +400,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
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=
@@ -451,10 +460,14 @@ 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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.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.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
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=
@@ -465,6 +478,8 @@ 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.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.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=

View File

@@ -1,27 +1,20 @@
package sdk
import (
_ "embed"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"github.com/charmbracelet/log"
"github.com/sailpoint-oss/sailpoint-cli/internal/util"
)
type Message struct {
Locale string `json:"locale,omitempty"`
LocaleOrigin string `json:"localeOrigin,omitempty"`
Text string `json:"text,omitempty"`
}
type SDKResp struct {
DetailCode string `json:"detailCode,omitempty"`
TrackingID string `json:"trackingId,omitempty"`
Messages []Message `json:"messages,omitempty"`
Causes []interface{} `json:"causes,omitempty"`
}
//go:embed sdkErr.md
var sdkErrBody string
var sdkErrParts = strings.Split(sdkErrBody, "====")
func HandleSDKError(resp *http.Response, sdkErr error) error {
defer resp.Body.Close()
@@ -31,22 +24,12 @@ func HandleSDKError(resp *http.Response, sdkErr error) error {
log.Error(err)
}
var formattedBody SDKResp
err = json.Unmarshal(body, &formattedBody)
var data map[string]interface{}
err = json.Unmarshal(body, &data)
if err != nil {
log.Error(err)
}
outputErr := fmt.Sprintf("%s\ndate: %s\nslpt-request-id: %s\nmsgs:\n", sdkErr, resp.Header["Date"][0], resp.Header["Slpt-Request-Id"][0])
if len(formattedBody.Messages) > 0 {
for _, v := range formattedBody.Messages {
outputErr = outputErr + fmt.Sprintf("%s\n", v.Text)
}
} else if len(body) > 0 {
outputErr = outputErr + fmt.Sprintf("%s\n", string(body))
}
return errors.New(outputErr)
return errors.New(util.RenderMarkdown(sdkErrParts[0] + util.PrettyPrint(resp.Header) + sdkErrParts[1] + util.PrettyPrint(data) + sdkErrParts[2]))
}

12
internal/sdk/sdkErr.md Normal file
View File

@@ -0,0 +1,12 @@
# Issues calling API
## Headers:
```json
====
```
## Body:
```json
====
```

View File

@@ -23,13 +23,9 @@ func init() {
// goes wrong. This will exit the cli container during pipeline build and fail that stage.
func main() {
err := rootCmd.Execute()
_ = rootCmd.Execute()
if saveErr := config.SaveConfig(); saveErr != nil {
log.Warn("Issue saving config file", "error", saveErr)
}
if err != nil {
log.Fatal(err)
}
}