Skip to content

Commit 4201429

Browse files
committed
Use kong instead of kingpin
Signed-off-by: Gábor Lipták <gliptak@gmail.com>
1 parent 65195ee commit 4201429

File tree

4 files changed

+104
-206
lines changed

4 files changed

+104
-206
lines changed

cmd/saml2aws/main.go

Lines changed: 54 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package main
22

33
import (
4-
"crypto/tls"
4+
//"crypto/tls"
55
"io"
66
"log"
77
"net/http"
88
"os"
99
"runtime"
1010

11-
"github.com/alecthomas/kingpin/v2"
11+
"github.com/alecthomas/kong"
1212
"github.com/sirupsen/logrus"
13-
"github.com/versent/saml2aws/v2"
1413
"github.com/versent/saml2aws/v2/cmd/saml2aws/commands"
1514
"github.com/versent/saml2aws/v2/pkg/flags"
1615
"github.com/versent/saml2aws/v2/pkg/prompter"
@@ -21,32 +20,38 @@ var (
2120
Version = "1.0.0"
2221
)
2322

24-
// The `cmdLineList` type is used to make a `[]string` meet the requirements
25-
// of the kingpin.Value interface
26-
type cmdLineList []string
23+
type CLI struct {
24+
Verbose bool `help:"Enable verbose logging"`
25+
Quiet bool `help:"Silences logs"`
2726

28-
func (i *cmdLineList) Set(value string) error {
29-
*i = append(*i, value)
27+
Configure struct {
28+
flags.CommonFlags
29+
} `cmd:"" help:"Configure a new IDP account"`
3030

31-
return nil
32-
}
31+
Login struct {
32+
flags.LoginExecFlags
33+
} `cmd:"" help:"Login to a SAML 2.0 IDP and convert the SAML assertion to an STS token"`
3334

34-
func (i *cmdLineList) String() string {
35-
return ""
36-
}
35+
Exec struct {
36+
flags.LoginExecFlags
37+
Command []string `arg:"" name:"command" help:"The command to execute"`
38+
} `cmd:"" help:"Exec the supplied command with env vars from STS token"`
3739

38-
func (i *cmdLineList) IsCumulative() bool {
39-
return true
40-
}
40+
Console struct {
41+
flags.ConsoleFlags
42+
} `cmd:"" help:"Console will open the aws console after logging in"`
4143

42-
func buildCmdList(s kingpin.Settings) (target *[]string) {
43-
target = new([]string)
44-
s.SetValue((*cmdLineList)(target))
45-
return
44+
ListRoles struct {
45+
flags.LoginExecFlags
46+
} `cmd:"" help:"List available role ARNs"`
47+
48+
Script struct {
49+
flags.LoginExecFlags
50+
Shell string `help:"Type of shell environment" default:"bash" enum:"bash,/bin/sh,powershell,fish,env"`
51+
} `cmd:"" help:"Emit a script that will export environment variables"`
4652
}
4753

4854
func main() {
49-
5055
log.SetOutput(os.Stderr)
5156
prompter.SetOutputWriter(os.Stderr)
5257
log.SetFlags(0)
@@ -59,153 +64,47 @@ func main() {
5964
logrus.SetOutput(os.Stdout)
6065
}
6166

62-
app := kingpin.New("saml2aws", "A command line tool to help with SAML access to the AWS token service.")
63-
app.Version(Version)
64-
65-
// Settings not related to commands
66-
verbose := app.Flag("verbose", "Enable verbose logging").Bool()
67-
quiet := app.Flag("quiet", "silences logs").Bool()
68-
69-
provider := app.Flag("provider", "This flag is obsolete. See: https://github.com/Versent/saml2aws#configuring-idp-accounts").Short('i').Enum("Akamai", "AzureAD", "ADFS", "ADFS2", "Browser", "Ping", "JumpCloud", "Okta", "OneLogin", "PSU", "KeyCloak")
70-
71-
// Common (to all commands) settings
72-
commonFlags := new(flags.CommonFlags)
73-
app.Flag("config", "Path/filename of saml2aws config file (env: SAML2AWS_CONFIGFILE)").Envar("SAML2AWS_CONFIGFILE").StringVar(&commonFlags.ConfigFile)
74-
app.Flag("idp-account", "The name of the configured IDP account. (env: SAML2AWS_IDP_ACCOUNT)").Envar("SAML2AWS_IDP_ACCOUNT").Short('a').Default("default").StringVar(&commonFlags.IdpAccount)
75-
app.Flag("idp-provider", "The configured IDP provider. (env: SAML2AWS_IDP_PROVIDER)").Envar("SAML2AWS_IDP_PROVIDER").EnumVar(&commonFlags.IdpProvider, saml2aws.MFAsByProvider.Names()...)
76-
app.Flag("browser-type", "The configured browser type when the IDP provider is set to Browser. if not set 'chromium' will be used. (env: SAML2AWS_BROWSER_TYPE)").Envar("SAML2AWS_BROWSER_TYPE").EnumVar(&commonFlags.BrowserType, "chromium", "firefox", "webkit", "chrome", "chrome-beta", "chrome-dev", "chrome-canary", "msedge", "msedge-beta", "msedge-dev", "msedge-canary")
77-
app.Flag("browser-executable-path", "The configured browser full path when the IDP provider is set to Browser. If set, no browser download will be performed and the executable path will be used instead. (env: SAML2AWS_BROWSER_EXECUTABLE_PATH)").Envar("SAML2AWS_BROWSER_EXECUTABLE_PATH").StringVar(&commonFlags.BrowserExecutablePath)
78-
app.Flag("browser-autofill", "Configures browser to autofill the username and password. (env: SAML2AWS_BROWSER_AUTOFILL)").Envar("SAML2AWS_BROWSER_AUTOFILL").BoolVar(&commonFlags.BrowserAutoFill)
79-
app.Flag("mfa", "The name of the mfa. (env: SAML2AWS_MFA)").Envar("SAML2AWS_MFA").StringVar(&commonFlags.MFA)
80-
app.Flag("skip-verify", "Skip verification of server certificate. (env: SAML2AWS_SKIP_VERIFY)").Envar("SAML2AWS_SKIP_VERIFY").Short('s').BoolVar(&commonFlags.SkipVerify)
81-
app.Flag("url", "The URL of the SAML IDP server used to login. (env: SAML2AWS_URL)").Envar("SAML2AWS_URL").StringVar(&commonFlags.URL)
82-
app.Flag("username", "The username used to login. (env: SAML2AWS_USERNAME)").Envar("SAML2AWS_USERNAME").StringVar(&commonFlags.Username)
83-
app.Flag("password", "The password used to login. (env: SAML2AWS_PASSWORD)").Envar("SAML2AWS_PASSWORD").StringVar(&commonFlags.Password)
84-
app.Flag("mfa-token", "The current MFA token (supported in Keycloak, ADFS, GoogleApps). (env: SAML2AWS_MFA_TOKEN)").Envar("SAML2AWS_MFA_TOKEN").StringVar(&commonFlags.MFAToken)
85-
app.Flag("role", "The ARN of the role to assume. (env: SAML2AWS_ROLE)").Envar("SAML2AWS_ROLE").StringVar(&commonFlags.RoleArn)
86-
app.Flag("policyfile", "The file containing the supplemental AssumeRole policy. (env: SAML2AWS_POLICY_FILE)").Envar("SAML2AWS_POLICY_FILE").StringVar(&commonFlags.PolicyFile)
87-
app.Flag("policyarns", "The ARN of supplemental policies to restrict the token. (env: SAML2AWS_POLICY_ARNS)").Envar("SAML2AWS_POLICY_ARNS").StringVar(&commonFlags.PolicyARNs)
88-
app.Flag("aws-urn", "The URN used by SAML when you login. (env: SAML2AWS_AWS_URN)").Envar("SAML2AWS_AWS_URN").StringVar(&commonFlags.AmazonWebservicesURN)
89-
app.Flag("skip-prompt", "Skip prompting for parameters during login.").BoolVar(&commonFlags.SkipPrompt)
90-
app.Flag("session-duration", "The duration of your AWS Session. (env: SAML2AWS_SESSION_DURATION)").Envar("SAML2AWS_SESSION_DURATION").IntVar(&commonFlags.SessionDuration)
91-
app.Flag("disable-keychain", "Do not use keychain at all. This will also disable Okta sessions & remembering MFA device. (env: SAML2AWS_DISABLE_KEYCHAIN)").Envar("SAML2AWS_DISABLE_KEYCHAIN").BoolVar(&commonFlags.DisableKeychain)
92-
app.Flag("region", "AWS region to use for API requests, e.g. us-east-1, us-gov-west-1, cn-north-1 (env: SAML2AWS_REGION)").Envar("SAML2AWS_REGION").Short('r').StringVar(&commonFlags.Region)
93-
app.Flag("prompter", "The prompter to use for user input (default, pinentry)").StringVar(&commonFlags.Prompter)
94-
app.Flag("kc-broker", "The kc broker to use when authenticating via keycloak").StringVar(&commonFlags.KCBroker)
95-
96-
// `configure` command and settings
97-
cmdConfigure := app.Command("configure", "Configure a new IDP account.")
98-
cmdConfigure.Flag("app-id", "OneLogin app id required for SAML assertion. (env: ONELOGIN_APP_ID)").Envar("ONELOGIN_APP_ID").StringVar(&commonFlags.AppID)
99-
cmdConfigure.Flag("client-id", "OneLogin client id, used to generate API access token. (env: ONELOGIN_CLIENT_ID)").Envar("ONELOGIN_CLIENT_ID").StringVar(&commonFlags.ClientID)
100-
cmdConfigure.Flag("client-secret", "OneLogin client secret, used to generate API access token. (env: ONELOGIN_CLIENT_SECRET)").Envar("ONELOGIN_CLIENT_SECRET").StringVar(&commonFlags.ClientSecret)
101-
cmdConfigure.Flag("subdomain", "OneLogin subdomain of your company account. (env: ONELOGIN_SUBDOMAIN)").Envar("ONELOGIN_SUBDOMAIN").StringVar(&commonFlags.Subdomain)
102-
cmdConfigure.Flag("mfa-ip-address", "IP address whitelisting defined in OneLogin MFA policies. (env: ONELOGIN_MFA_IP_ADDRESS)").Envar("ONELOGIN_MFA_IP_ADDRESS").StringVar(&commonFlags.MFAIPAddress)
103-
cmdConfigure.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Envar("SAML2AWS_PROFILE").Short('p').StringVar(&commonFlags.Profile)
104-
cmdConfigure.Flag("resource-id", "F5APM SAML resource ID of your company account. (env: SAML2AWS_F5APM_RESOURCE_ID)").Envar("SAML2AWS_F5APM_RESOURCE_ID").StringVar(&commonFlags.ResourceID)
105-
cmdConfigure.Flag("credentials-file", "The file that will cache the credentials retrieved from AWS. When not specified, will use the default AWS credentials file location. (env: SAML2AWS_CREDENTIALS_FILE)").Envar("SAML2AWS_CREDENTIALS_FILE").StringVar(&commonFlags.CredentialsFile)
106-
cmdConfigure.Flag("cache-saml", "Caches the SAML response (env: SAML2AWS_CACHE_SAML)").Envar("SAML2AWS_CACHE_SAML").BoolVar(&commonFlags.SAMLCache)
107-
cmdConfigure.Flag("cache-file", "The location of the SAML cache file (env: SAML2AWS_SAML_CACHE_FILE)").Envar("SAML2AWS_SAML_CACHE_FILE").StringVar(&commonFlags.SAMLCacheFile)
108-
cmdConfigure.Flag("disable-sessions", "Do not use Okta sessions. Uses Okta sessions by default. (env: SAML2AWS_OKTA_DISABLE_SESSIONS)").Envar("SAML2AWS_OKTA_DISABLE_SESSIONS").BoolVar(&commonFlags.DisableSessions)
109-
cmdConfigure.Flag("disable-remember-device", "Do not remember Okta MFA device. Remembers MFA device by default. (env: SAML2AWS_OKTA_DISABLE_REMEMBER_DEVICE)").Envar("SAML2AWS_OKTA_DISABLE_REMEMBER_DEVICE").BoolVar(&commonFlags.DisableRememberDevice)
110-
configFlags := commonFlags
111-
112-
// `login` command and settings
113-
cmdLogin := app.Command("login", "Login to a SAML 2.0 IDP and convert the SAML assertion to an STS token.")
114-
loginFlags := new(flags.LoginExecFlags)
115-
loginFlags.CommonFlags = commonFlags
116-
cmdLogin.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Short('p').Envar("SAML2AWS_PROFILE").StringVar(&commonFlags.Profile)
117-
cmdLogin.Flag("duo-mfa-option", "The MFA option you want to use to authenticate with (supported providers: okta). (env: SAML2AWS_DUO_MFA_OPTION)").Envar("SAML2AWS_DUO_MFA_OPTION").EnumVar(&loginFlags.DuoMFAOption, "Passcode", "Duo Push")
118-
cmdLogin.Flag("client-id", "OneLogin client id, used to generate API access token. (env: ONELOGIN_CLIENT_ID)").Envar("ONELOGIN_CLIENT_ID").StringVar(&commonFlags.ClientID)
119-
cmdLogin.Flag("client-secret", "OneLogin client secret, used to generate API access token. (env: ONELOGIN_CLIENT_SECRET)").Envar("ONELOGIN_CLIENT_SECRET").StringVar(&commonFlags.ClientSecret)
120-
cmdLogin.Flag("mfa-ip-address", "IP address whitelisting defined in OneLogin MFA policies. (env: ONELOGIN_MFA_IP_ADDRESS)").Envar("ONELOGIN_MFA_IP_ADDRESS").StringVar(&commonFlags.MFAIPAddress)
121-
cmdLogin.Flag("force", "Refresh credentials even if not expired.").BoolVar(&loginFlags.Force)
122-
cmdLogin.Flag("credential-process", "Enables AWS Credential Process support by outputting credentials to STDOUT in a JSON message.").BoolVar(&loginFlags.CredentialProcess)
123-
cmdLogin.Flag("credentials-file", "The file that will cache the credentials retrieved from AWS. When not specified, will use the default AWS credentials file location. (env: SAML2AWS_CREDENTIALS_FILE)").Envar("SAML2AWS_CREDENTIALS_FILE").StringVar(&commonFlags.CredentialsFile)
124-
cmdLogin.Flag("cache-saml", "Caches the SAML response (env: SAML2AWS_CACHE_SAML)").Envar("SAML2AWS_CACHE_SAML").BoolVar(&commonFlags.SAMLCache)
125-
cmdLogin.Flag("cache-file", "The location of the SAML cache file (env: SAML2AWS_SAML_CACHE_FILE)").Envar("SAML2AWS_SAML_CACHE_FILE").StringVar(&commonFlags.SAMLCacheFile)
126-
cmdLogin.Flag("download-browser-driver", "Automatically download browsers for Browser IDP. (env: SAML2AWS_AUTO_BROWSER_DOWNLOAD)").Envar("SAML2AWS_AUTO_BROWSER_DOWNLOAD").BoolVar(&loginFlags.DownloadBrowser)
127-
cmdLogin.Flag("disable-sessions", "Do not use Okta sessions. Uses Okta sessions by default. (env: SAML2AWS_OKTA_DISABLE_SESSIONS)").Envar("SAML2AWS_OKTA_DISABLE_SESSIONS").BoolVar(&commonFlags.DisableSessions)
128-
cmdLogin.Flag("disable-remember-device", "Do not remember Okta MFA device. Remembers MFA device by default. (env: SAML2AWS_OKTA_DISABLE_REMEMBER_DEVICE)").Envar("SAML2AWS_OKTA_DISABLE_REMEMBER_DEVICE").BoolVar(&commonFlags.DisableRememberDevice)
129-
cmdLogin.Flag("try-no-prompt", "Only prompt for credentials if they cannot be read from keyring").BoolVar(&loginFlags.TryNoPrompt)
130-
131-
// `exec` command and settings
132-
cmdExec := app.Command("exec", "Exec the supplied command with env vars from STS token.")
133-
execFlags := new(flags.LoginExecFlags)
134-
execFlags.CommonFlags = commonFlags
135-
cmdExec.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Envar("SAML2AWS_PROFILE").Short('p').StringVar(&commonFlags.Profile)
136-
cmdExec.Flag("exec-profile", "The AWS profile to utilize for command execution. Useful to allow the aws cli to perform secondary role assumption. (env: SAML2AWS_EXEC_PROFILE)").Envar("SAML2AWS_EXEC_PROFILE").StringVar(&execFlags.ExecProfile)
137-
cmdExec.Flag("credentials-file", "The file that will cache the credentials retrieved from AWS. When not specified, will use the default AWS credentials file location. (env: SAML2AWS_CREDENTIALS_FILE)").Envar("SAML2AWS_CREDENTIALS_FILE").StringVar(&commonFlags.CredentialsFile)
138-
cmdLine := buildCmdList(cmdExec.Arg("command", "The command to execute."))
139-
140-
// `console` command and settings
141-
cmdConsole := app.Command("console", "Console will open the aws console after logging in.")
142-
consoleFlags := new(flags.ConsoleFlags)
143-
consoleFlags.LoginExecFlags = execFlags
144-
consoleFlags.LoginExecFlags.CommonFlags = commonFlags
145-
cmdConsole.Flag("exec-profile", "The AWS profile to utilize for console execution. (env: SAML2AWS_EXEC_PROFILE)").Envar("SAML2AWS_EXEC_PROFILE").StringVar(&consoleFlags.LoginExecFlags.ExecProfile)
146-
cmdConsole.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Envar("SAML2AWS_PROFILE").Short('p').StringVar(&commonFlags.Profile)
147-
cmdConsole.Flag("force", "Refresh credentials even if not expired.").BoolVar(&consoleFlags.LoginExecFlags.Force)
148-
cmdConsole.Flag("link", "Present link to AWS console instead of opening browser").BoolVar(&consoleFlags.Link)
149-
cmdConsole.Flag("credentials-file", "The file that will cache the credentials retrieved from AWS. When not specified, will use the default AWS credentials file location. (env: SAML2AWS_CREDENTIALS_FILE)").Envar("SAML2AWS_CREDENTIALS_FILE").StringVar(&commonFlags.CredentialsFile)
150-
151-
// `list` command and settings
152-
cmdListRoles := app.Command("list-roles", "List available role ARNs.")
153-
cmdListRoles.Flag("cache-saml", "Caches the SAML response (env: SAML2AWS_CACHE_SAML)").Envar("SAML2AWS_CACHE_SAML").BoolVar(&commonFlags.SAMLCache)
154-
cmdListRoles.Flag("cache-file", "The location of the SAML cache file (env: SAML2AWS_SAML_CACHE_FILE)").Envar("SAML2AWS_SAML_CACHE_FILE").StringVar(&commonFlags.SAMLCacheFile)
155-
listRolesFlags := new(flags.LoginExecFlags)
156-
listRolesFlags.CommonFlags = commonFlags
157-
158-
// `script` command and settings
159-
cmdScript := app.Command("script", "Emit a script that will export environment variables.")
160-
scriptFlags := new(flags.LoginExecFlags)
161-
scriptFlags.CommonFlags = commonFlags
162-
cmdScript.Flag("profile", "The AWS profile to save the temporary credentials. (env: SAML2AWS_PROFILE)").Envar("SAML2AWS_PROFILE").Short('p').StringVar(&commonFlags.Profile)
163-
cmdScript.Flag("credentials-file", "The file that will cache the credentials retrieved from AWS. When not specified, will use the default AWS credentials file location. (env: SAML2AWS_CREDENTIALS_FILE)").Envar("SAML2AWS_CREDENTIALS_FILE").StringVar(&commonFlags.CredentialsFile)
164-
var shell string
165-
cmdScript.
166-
Flag("shell", "Type of shell environment. Options include: bash, /bin/sh, powershell, fish, env").
167-
Default("bash").
168-
EnumVar(&shell, "bash", "/bin/sh", "powershell", "fish", "env")
169-
170-
// Trigger the parsing of the command line inputs via kingpin
171-
command := kingpin.MustParse(app.Parse(os.Args[1:]))
172-
173-
// will leave this here for a while during upgrade process
174-
if *provider != "" {
175-
log.Println("The --provider flag has been replaced with a new configure command. See https://github.com/Versent/saml2aws#configuring-idp-accounts")
176-
os.Exit(1)
177-
}
178-
67+
var cli CLI
68+
ctx := kong.Parse(&cli,
69+
kong.Name("saml2aws"),
70+
kong.Description("A command line tool to help with SAML access to the AWS token service."),
71+
kong.Vars{
72+
"version": Version,
73+
},
74+
)
17975
errtpl := "%v\n"
180-
if *verbose {
76+
if cli.Verbose {
18177
logrus.SetLevel(logrus.DebugLevel)
18278
errtpl = "%+v\n"
18379
}
18480

185-
if *quiet {
81+
if cli.Quiet {
18682
log.SetOutput(io.Discard)
18783
logrus.SetOutput(io.Discard)
18884
}
18985

19086
// Set the default transport settings so all http clients will pick them up.
191-
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: commonFlags.SkipVerify}
87+
//http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: cli.CommonFlags.SkipVerify}
19288
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
19389

194-
logrus.WithField("command", command).Debug("Running")
90+
logrus.WithField("command", ctx.Command()).Debug("Running")
91+
19592
var err error
196-
switch command {
197-
case cmdScript.FullCommand():
198-
err = commands.Script(scriptFlags, shell)
199-
case cmdLogin.FullCommand():
200-
err = commands.Login(loginFlags)
201-
case cmdExec.FullCommand():
202-
err = commands.Exec(execFlags, *cmdLine)
203-
case cmdConsole.FullCommand():
204-
err = commands.Console(consoleFlags)
205-
case cmdListRoles.FullCommand():
206-
err = commands.ListRoles(listRolesFlags)
207-
case cmdConfigure.FullCommand():
208-
err = commands.Configure(configFlags)
93+
switch ctx.Command() {
94+
case "script":
95+
err = commands.Script(&cli.Script.LoginExecFlags, cli.Script.Shell)
96+
case "login":
97+
err = commands.Login(&cli.Login.LoginExecFlags)
98+
case "exec":
99+
err = commands.Exec(&cli.Exec.LoginExecFlags, cli.Exec.Command)
100+
case "console":
101+
err = commands.Console(&cli.Console.ConsoleFlags)
102+
case "list-roles":
103+
err = commands.ListRoles(&cli.ListRoles.LoginExecFlags)
104+
case "configure":
105+
err = commands.Configure(&cli.Configure.CommonFlags)
106+
default:
107+
err = ctx.Run()
209108
}
210109

211110
if err != nil {

go.mod

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/AlecAivazis/survey/v2 v2.3.7
1010
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e
1111
github.com/PuerkitoBio/goquery v1.9.2
12-
github.com/alecthomas/kingpin/v2 v2.4.0
12+
github.com/alecthomas/kong v1.13.0
1313
github.com/avast/retry-go v3.0.0+incompatible
1414
github.com/aws/aws-sdk-go v1.55.6
1515
github.com/beevik/etree v1.4.1
@@ -32,7 +32,6 @@ require (
3232

3333
require (
3434
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
35-
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
3635
github.com/andybalholm/cascadia v1.3.2 // indirect
3736
github.com/bearsh/hid v1.3.0 // indirect
3837
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -53,7 +52,6 @@ require (
5352
github.com/stretchr/objx v0.5.2 // indirect
5453
github.com/tidwall/match v1.1.1 // indirect
5554
github.com/tidwall/pretty v1.2.1 // indirect
56-
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
5755
go.uber.org/multierr v1.11.0 // indirect
5856
golang.org/x/crypto v0.31.0 // indirect
5957
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect

0 commit comments

Comments
 (0)