diff --git a/.circleci/config.yml b/.circleci/config.yml index 8294d0e714..25493b1ec6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -778,9 +778,9 @@ jobs: false fi - run: - name: "Verify Kurtosis cleaned up all its volumes (except for the log storage volume, so we can persist service logs)" + name: "Verify Kurtosis cleaned up all its volumes (except for the log storage and github auth storage volumes)" command: | - if ! [ $(docker volume ls | grep -v kurtosis-logs-collector-vol | grep -v kurtosis-logs-db-vol | tail -n+2 | wc -l ) -eq 1 ]; then + if ! [ $(docker volume ls | grep -v kurtosis-logs-collector-vol | grep -v kurtosis-logs-db-vol | tail -n+2 | wc -l ) -eq 2 ]; then docker volume ls false fi @@ -1013,9 +1013,9 @@ jobs: false fi - run: - name: "Verify Kurtosis cleaned up all its volumes (except for the log storage volume, so we can persist service logs)" + name: "Verify Kurtosis cleaned up all its volumes (except for the log storage and github auth storage volumes)" command: | - if ! [ $(docker volume ls | grep -v kurtosis-logs-collector-vol | grep -v kurtosis-logs-db-vol | tail -n+2 | wc -l) -eq 1 ]; then + if ! [ $(docker volume ls | grep -v kurtosis-logs-collector-vol | grep -v kurtosis-logs-db-vol | tail -n+2 | wc -l) -eq 2 ]; then docker volume ls false fi diff --git a/cli/cli/command_framework/highlevel/engine_consuming_kurtosis_command/engine_consuming_kurtosis_command.go b/cli/cli/command_framework/highlevel/engine_consuming_kurtosis_command/engine_consuming_kurtosis_command.go index a909a211e3..b4d3c12b2e 100644 --- a/cli/cli/command_framework/highlevel/engine_consuming_kurtosis_command/engine_consuming_kurtosis_command.go +++ b/cli/cli/command_framework/highlevel/engine_consuming_kurtosis_command/engine_consuming_kurtosis_command.go @@ -186,7 +186,7 @@ func (cmd *EngineConsumingKurtosisCommand) getSetupFunc() func(context.Context) // commands only access the Kurtosis APIs, we can remove this. kurtosisBackend := engineManager.GetKurtosisBackend() - engineClient, closeClientFunc, err := engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, defaults.DefaultEngineLogLevel, defaults.DefaultEngineEnclavePoolSize) + engineClient, closeClientFunc, err := engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, defaults.DefaultEngineLogLevel, defaults.DefaultEngineEnclavePoolSize, defaults.DefaultGitHubAuthTokenOverride) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred creating a new Kurtosis engine client") } diff --git a/cli/cli/command_str_consts/command_str_consts.go b/cli/cli/command_str_consts/command_str_consts.go index 2f39bc320d..bf5ec0416e 100644 --- a/cli/cli/command_str_consts/command_str_consts.go +++ b/cli/cli/command_str_consts/command_str_consts.go @@ -76,6 +76,11 @@ const ( PortCmdStr = "port" PortPrintCmdStr = "print" WebCmdStr = "web" + GitHubCmdStr = "github" + GitHubLoginCmdStr = "login" + GitHubLogoutCmdStr = "logout" + GitHubTokenCmdStr = "token" + GitHubStatusCmdStr = "status" ) // TODO: added constant error message here, can we move to another file later. diff --git a/cli/cli/commands/cluster/set/set.go b/cli/cli/commands/cluster/set/set.go index 208b8c6fd5..6600fc1233 100644 --- a/cli/cli/commands/cluster/set/set.go +++ b/cli/cli/commands/cluster/set/set.go @@ -123,7 +123,7 @@ func run(ctx context.Context, flags *flags.ParsedFlags, args *args.ParsedArgs) e // we only start in a stopped state, the idempotent visitor gets stuck with engine_manager.EngineStatus_ContainerRunningButServerNotResponding if the gateway isn't running // TODO - fix the idempotent starter longer term if engineStatus == engine_manager.EngineStatus_Stopped { - _, engineClientCloseFunc, err := engineManagerNewCluster.StartEngineIdempotentlyWithDefaultVersion(ctx, defaults.DefaultEngineLogLevel, defaults.DefaultEngineEnclavePoolSize) + _, engineClientCloseFunc, err := engineManagerNewCluster.StartEngineIdempotentlyWithDefaultVersion(ctx, defaults.DefaultEngineLogLevel, defaults.DefaultEngineEnclavePoolSize, defaults.DefaultGitHubAuthTokenOverride) if err != nil { return stacktrace.Propagate(err, "Engine could not be started after cluster was updated. Its status can be retrieved "+ "running 'kurtosis %s %s' and it can potentially be started running 'kurtosis %s %s'", diff --git a/cli/cli/commands/enclave/add/add.go b/cli/cli/commands/enclave/add/add.go index e9cbb57c0a..9d0e628e5a 100644 --- a/cli/cli/commands/enclave/add/add.go +++ b/cli/cli/commands/enclave/add/add.go @@ -119,8 +119,7 @@ func run( if err != nil { return stacktrace.Propagate(err, "An error occurred creating an engine manager.") } - - engineClient, closeClientFunc, err := engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, defaults.DefaultEngineLogLevel, defaults.DefaultEngineEnclavePoolSize) + engineClient, closeClientFunc, err := engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, defaults.DefaultEngineLogLevel, defaults.DefaultEngineEnclavePoolSize, defaults.DefaultGitHubAuthTokenOverride) if err != nil { return stacktrace.Propagate(err, "An error occurred creating a new Kurtosis engine client") } diff --git a/cli/cli/commands/engine/restart/restart.go b/cli/cli/commands/engine/restart/restart.go index a45ae86dab..b039800d66 100644 --- a/cli/cli/commands/engine/restart/restart.go +++ b/cli/cli/commands/engine/restart/restart.go @@ -19,9 +19,10 @@ import ( ) const ( - engineVersionFlagKey = "version" - logLevelFlagKey = "log-level" - enclavePoolSizeFlagKey = "enclave-pool-size" + engineVersionFlagKey = "version" + logLevelFlagKey = "log-level" + enclavePoolSizeFlagKey = "enclave-pool-size" + githubAuthTokenOverrideFlagKey = "github-auth-token" defaultEngineVersion = "" restartEngineOnSameVersionIfAnyRunning = false @@ -63,6 +64,13 @@ var RestartCmd = &lowlevel.LowlevelKurtosisCommand{ Type: flags.FlagType_Uint8, Default: strconv.Itoa(int(defaults.DefaultEngineEnclavePoolSize)), }, + { + Key: githubAuthTokenOverrideFlagKey, + Usage: "The GitHub auth token that should be used to authorize git operations such as accessing packages in private repositories. Overrides existing GitHub auth config if a user is logged in.", + Shorthand: "", + Type: flags.FlagType_String, + Default: defaults.DefaultGitHubAuthTokenOverride, + }, }, PreValidationAndRunFunc: nil, RunFunc: run, @@ -93,6 +101,11 @@ func run(_ context.Context, flags *flags.ParsedFlags, _ *args.ParsedArgs) error return stacktrace.Propagate(err, "An error occurred parsing log level string '%v'", logLevelStr) } + githubAuthTokenOverride, err := flags.GetString(githubAuthTokenOverrideFlagKey) + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting GitHub auth token override flag with key '%v'. This is a bug in Kurtosis", githubAuthTokenOverrideFlagKey) + } + engineManager, err := engine_manager.NewEngineManager(ctx) if err != nil { return stacktrace.Propagate(err, "An error occurred creating an engine manager.") @@ -116,7 +129,7 @@ func run(_ context.Context, flags *flags.ParsedFlags, _ *args.ParsedArgs) error var engineClientCloseFunc func() error var restartEngineErr error - _, engineClientCloseFunc, restartEngineErr = engineManager.RestartEngineIdempotently(ctx, logLevel, engineVersion, restartEngineOnSameVersionIfAnyRunning, enclavePoolSize, shouldStartInDebugMode) + _, engineClientCloseFunc, restartEngineErr = engineManager.RestartEngineIdempotently(ctx, logLevel, engineVersion, restartEngineOnSameVersionIfAnyRunning, enclavePoolSize, shouldStartInDebugMode, githubAuthTokenOverride) if restartEngineErr != nil { return stacktrace.Propagate(restartEngineErr, "An error occurred restarting the Kurtosis engine") } diff --git a/cli/cli/commands/engine/start/start.go b/cli/cli/commands/engine/start/start.go index 86f93089e2..53802f48bd 100644 --- a/cli/cli/commands/engine/start/start.go +++ b/cli/cli/commands/engine/start/start.go @@ -19,9 +19,10 @@ import ( ) const ( - engineVersionFlagKey = "version" - logLevelFlagKey = "log-level" - enclavePoolSizeFlagKey = "enclave-pool-size" + engineVersionFlagKey = "version" + logLevelFlagKey = "log-level" + enclavePoolSizeFlagKey = "enclave-pool-size" + githubAuthTokenOverrideFlagKey = "github-auth-token" defaultEngineVersion = "" kurtosisTechEngineImagePrefix = "kurtosistech/engine" @@ -64,6 +65,13 @@ var StartCmd = &lowlevel.LowlevelKurtosisCommand{ Type: flags.FlagType_Uint8, Default: strconv.Itoa(int(defaults.DefaultEngineEnclavePoolSize)), }, + { + Key: githubAuthTokenOverrideFlagKey, + Usage: "The github auth token that should be used to authorize git operations such as accessing packages in private repositories. Overrides existing github auth config if a user is logged in.", + Shorthand: "", + Type: flags.FlagType_String, + Default: defaults.DefaultGitHubAuthTokenOverride, + }, }, PreValidationAndRunFunc: nil, RunFunc: run, @@ -92,6 +100,11 @@ func run(_ context.Context, flags *flags.ParsedFlags, _ *args.ParsedArgs) error return stacktrace.Propagate(err, "An error occurred parsing log level string '%v'", logLevelStr) } + githubAuthTokenOverride, err := flags.GetString(githubAuthTokenOverrideFlagKey) + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting GitHub auth token override flag with key '%v'. This is a bug in Kurtosis", githubAuthTokenOverrideFlagKey) + } + engineManager, err := engine_manager.NewEngineManager(ctx) if err != nil { return stacktrace.Propagate(err, "An error occurred creating an engine manager") @@ -113,14 +126,13 @@ func run(_ context.Context, flags *flags.ParsedFlags, _ *args.ParsedArgs) error if engineVersion == defaultEngineVersion && isDebugMode { engineDebugVersion := fmt.Sprintf("%s-%s", kurtosis_version.KurtosisVersion, defaults.DefaultKurtosisContainerDebugImageNameSuffix) logrus.Infof("Starting Kurtosis engine in debug mode from image '%v%v%v'...", kurtosisTechEngineImagePrefix, imageVersionDelimiter, engineDebugVersion) - _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithCustomVersion(ctx, engineDebugVersion, logLevel, enclavePoolSize, true) + _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithCustomVersion(ctx, engineDebugVersion, logLevel, enclavePoolSize, true, githubAuthTokenOverride) } else if engineVersion == defaultEngineVersion { - logrus.Infof("Starting Kurtosis engine from image '%v%v%v'...", kurtosisTechEngineImagePrefix, imageVersionDelimiter, kurtosis_version.KurtosisVersion) - _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, logLevel, enclavePoolSize) + _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, logLevel, enclavePoolSize, githubAuthTokenOverride) } else { logrus.Infof("Starting Kurtosis engine from image '%v%v%v'...", kurtosisTechEngineImagePrefix, imageVersionDelimiter, engineVersion) - _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithCustomVersion(ctx, engineVersion, logLevel, enclavePoolSize, defaults.DefaultEnableDebugMode) + _, engineClientCloseFunc, startEngineErr = engineManager.StartEngineIdempotentlyWithCustomVersion(ctx, engineVersion, logLevel, enclavePoolSize, defaults.DefaultEnableDebugMode, githubAuthTokenOverride) } if startEngineErr != nil { return stacktrace.Propagate(startEngineErr, "An error occurred starting the Kurtosis engine") diff --git a/cli/cli/commands/github/github.go b/cli/cli/commands/github/github.go new file mode 100644 index 0000000000..de7c451d78 --- /dev/null +++ b/cli/cli/commands/github/github.go @@ -0,0 +1,25 @@ +package github + +import ( + "github.com/kurtosis-tech/kurtosis/cli/cli/command_str_consts" + "github.com/kurtosis-tech/kurtosis/cli/cli/commands/github/login" + "github.com/kurtosis-tech/kurtosis/cli/cli/commands/github/logout" + "github.com/kurtosis-tech/kurtosis/cli/cli/commands/github/status" + "github.com/kurtosis-tech/kurtosis/cli/cli/commands/github/token" + "github.com/spf13/cobra" +) + +// GitHubCmd Suppressing exhaustruct requirement because this struct has ~40 properties +// nolint: exhaustruct +var GitHubCmd = &cobra.Command{ + Use: command_str_consts.GitHubCmdStr, + Short: "Manage GitHub login", + RunE: nil, +} + +func init() { + GitHubCmd.AddCommand(login.LoginCmd.MustGetCobraCommand()) + GitHubCmd.AddCommand(logout.LogoutCmd.MustGetCobraCommand()) + GitHubCmd.AddCommand(status.StatusCmd.MustGetCobraCommand()) + GitHubCmd.AddCommand(token.TokenCmd.MustGetCobraCommand()) +} diff --git a/cli/cli/commands/github/login/login.go b/cli/cli/commands/github/login/login.go new file mode 100644 index 0000000000..3702e405a4 --- /dev/null +++ b/cli/cli/commands/github/login/login.go @@ -0,0 +1,50 @@ +package login + +import ( + "context" + "fmt" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel/args" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel/flags" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_str_consts" + "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/github_auth_store" + "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/oauth" + "github.com/kurtosis-tech/kurtosis/cli/cli/out" + "github.com/kurtosis-tech/stacktrace" +) + +var LoginCmd = &lowlevel.LowlevelKurtosisCommand{ + CommandStr: command_str_consts.GitHubLoginCmdStr, + ShortDescription: "Authorizes Kurtosis CLI on behalf of a Github user.", + LongDescription: "Authorizes Kurtosis CLI to perform git operations on behalf of a GitHub user such as retrieving packages in private repositories.", + Args: nil, + Flags: nil, + PreValidationAndRunFunc: nil, + RunFunc: run, + PostValidationAndRunFunc: nil, +} + +func run(_ context.Context, _ *flags.ParsedFlags, _ *args.ParsedArgs) error { + githubAuthStore, err := github_auth_store.GetGitHubAuthStore() + if err != nil { + return stacktrace.Propagate(err, "An error occurred retrieving GitHub auth store.") + } + username, err := githubAuthStore.GetUser() + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting user to see if user already exists.") + } + if username != "" { + out.PrintOutLn(fmt.Sprintf("Logged in as GitHub user: %v", username)) + return nil + } + authToken, username, err := oauth.AuthFlow() + if err != nil { + return stacktrace.Propagate(err, "An error occurred in the Github OAuth flow.") + } + err = githubAuthStore.SetUser(username, authToken) + if err != nil { + return stacktrace.Propagate(err, "An error occurred setting GitHub user: %v", username) + } + out.PrintOutLn(fmt.Sprintf("Successfully logged in GitHub user: %v", username)) + return nil +} diff --git a/cli/cli/commands/github/logout/logout.go b/cli/cli/commands/github/logout/logout.go new file mode 100644 index 0000000000..a6ba7da499 --- /dev/null +++ b/cli/cli/commands/github/logout/logout.go @@ -0,0 +1,45 @@ +package logout + +import ( + "context" + "fmt" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel/args" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel/flags" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_str_consts" + "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/github_auth_store" + "github.com/kurtosis-tech/kurtosis/cli/cli/out" + "github.com/kurtosis-tech/stacktrace" +) + +var LogoutCmd = &lowlevel.LowlevelKurtosisCommand{ + CommandStr: command_str_consts.GitHubLogoutCmdStr, + ShortDescription: "Logs out a GitHub user from Kurtosis CLI", + LongDescription: "Logs out a GitHub user from Kurtosis CLI by removing their GitHub user info and auth token from Kurtosis CLI config", + Args: nil, + Flags: nil, + PreValidationAndRunFunc: nil, + RunFunc: run, + PostValidationAndRunFunc: nil, +} + +func run(_ context.Context, _ *flags.ParsedFlags, _ *args.ParsedArgs) error { + githubAuthStore, err := github_auth_store.GetGitHubAuthStore() + if err != nil { + return stacktrace.Propagate(err, "An error occurred retrieving GitHub auth configuration.") + } + username, err := githubAuthStore.GetUser() + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting user to see if user already exists.") + } + if username == "" { + out.PrintOutLn("No GitHub user logged into Kurtosis CLI: %v") + return nil + } + err = githubAuthStore.RemoveUser() + if err != nil { + return stacktrace.Propagate(err, "An error occurred logging out GitHub user: %v", username) + } + out.PrintOutLn(fmt.Sprintf("Successfully logged GitHub user '%v' out of Kurtosis CLI", username)) + return nil +} diff --git a/cli/cli/commands/github/status/status.go b/cli/cli/commands/github/status/status.go new file mode 100644 index 0000000000..c8fbf3441b --- /dev/null +++ b/cli/cli/commands/github/status/status.go @@ -0,0 +1,41 @@ +package status + +import ( + "context" + "fmt" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel/args" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel/flags" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_str_consts" + "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/github_auth_store" + "github.com/kurtosis-tech/kurtosis/cli/cli/out" + "github.com/kurtosis-tech/stacktrace" +) + +var StatusCmd = &lowlevel.LowlevelKurtosisCommand{ + CommandStr: command_str_consts.GitHubStatusCmdStr, + ShortDescription: "Displays GitHub auth info", + LongDescription: "Displays GitHub auth info by showing a logged in user's info or whether no GitHub user is logged into Kurtosis CLI", + Args: nil, + Flags: nil, + PreValidationAndRunFunc: nil, + RunFunc: run, + PostValidationAndRunFunc: nil, +} + +func run(_ context.Context, _ *flags.ParsedFlags, _ *args.ParsedArgs) error { + githubAuthStore, err := github_auth_store.GetGitHubAuthStore() + if err != nil { + return stacktrace.Propagate(err, "An error occurred retrieving GitHub auth configuration.") + } + username, err := githubAuthStore.GetUser() + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting user to see if user already exists.") + } + if username == "" { + out.PrintOutLn("No GitHub user logged into Kurtosis CLI") + return nil + } + out.PrintOutLn(fmt.Sprintf("Logged in as GitHub user: %v", username)) + return nil +} diff --git a/cli/cli/commands/github/token/token.go b/cli/cli/commands/github/token/token.go new file mode 100644 index 0000000000..fc27a68e53 --- /dev/null +++ b/cli/cli/commands/github/token/token.go @@ -0,0 +1,44 @@ +package token + +import ( + "context" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel/args" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/lowlevel/flags" + "github.com/kurtosis-tech/kurtosis/cli/cli/command_str_consts" + "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/github_auth_store" + "github.com/kurtosis-tech/kurtosis/cli/cli/out" + "github.com/kurtosis-tech/stacktrace" +) + +var TokenCmd = &lowlevel.LowlevelKurtosisCommand{ + CommandStr: command_str_consts.GitHubTokenCmdStr, + ShortDescription: "Displays GitHub auth token used if a user is logged in", + LongDescription: "Displays GitHub auth token used if a user is logged in", + Args: nil, + Flags: nil, + PreValidationAndRunFunc: nil, + RunFunc: run, + PostValidationAndRunFunc: nil, +} + +func run(_ context.Context, _ *flags.ParsedFlags, _ *args.ParsedArgs) error { + githubAuthStore, err := github_auth_store.GetGitHubAuthStore() + if err != nil { + return stacktrace.Propagate(err, "An error occurred retrieving GitHub auth store.") + } + username, err := githubAuthStore.GetUser() + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting user to see if user already exists.") + } + if username == "" { + out.PrintOutLn("No GitHub user currently logged in.") + return nil + } + authToken, err := githubAuthStore.GetAuthToken() + if err != nil { + return stacktrace.Propagate(err, "An error occurred retrieving GitHub auth token for user: %v.", username) + } + out.PrintOutLn(authToken) + return nil +} diff --git a/cli/cli/commands/kurtosis_context/set/set.go b/cli/cli/commands/kurtosis_context/set/set.go index 6818c111bc..f52d798cf7 100644 --- a/cli/cli/commands/kurtosis_context/set/set.go +++ b/cli/cli/commands/kurtosis_context/set/set.go @@ -147,7 +147,7 @@ func SetContext( return stacktrace.Propagate(err, "An error occurred creating an engine manager for the new context.") } - _, engineClientCloseFunc, startEngineErr := engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, logrus.InfoLevel, defaults.DefaultEngineEnclavePoolSize) + _, engineClientCloseFunc, startEngineErr := engineManager.StartEngineIdempotentlyWithDefaultVersion(ctx, logrus.InfoLevel, defaults.DefaultEngineEnclavePoolSize, defaults.DefaultGitHubAuthTokenOverride) if startEngineErr != nil { logrus.Warnf("The context was successfully set to '%s' but Kurtosis failed to start an engine in "+ "this new context. A new engine should be started manually with '%s %s %s'. The error was:\n%v", diff --git a/cli/cli/commands/root.go b/cli/cli/commands/root.go index 2aa5c563a9..f81cd735e8 100644 --- a/cli/cli/commands/root.go +++ b/cli/cli/commands/root.go @@ -23,6 +23,7 @@ import ( "github.com/kurtosis-tech/kurtosis/cli/cli/commands/feedback" "github.com/kurtosis-tech/kurtosis/cli/cli/commands/files" "github.com/kurtosis-tech/kurtosis/cli/cli/commands/gateway" + "github.com/kurtosis-tech/kurtosis/cli/cli/commands/github" _import "github.com/kurtosis-tech/kurtosis/cli/cli/commands/import" "github.com/kurtosis-tech/kurtosis/cli/cli/commands/kurtosis_context" "github.com/kurtosis-tech/kurtosis/cli/cli/commands/lint" @@ -138,6 +139,7 @@ func init() { RootCmd.AddCommand(version.VersionCmd) RootCmd.AddCommand(web.WebCmd.MustGetCobraCommand()) RootCmd.AddCommand(_package.PackageCmd) + RootCmd.AddCommand(github.GitHubCmd) } // ==================================================================================================== diff --git a/cli/cli/defaults/defaults.go b/cli/cli/defaults/defaults.go index 3f32456b1b..27e8032fd2 100644 --- a/cli/cli/defaults/defaults.go +++ b/cli/cli/defaults/defaults.go @@ -22,6 +22,8 @@ const ( DebugModeFlagKey = "debug-mode" DefaultEnableDebugMode = false DefaultKurtosisContainerDebugImageNameSuffix = "debug" + + DefaultGitHubAuthTokenOverride = "" ) var DefaultApiContainerLogLevel = logrus.DebugLevel diff --git a/cli/cli/go.mod b/cli/cli/go.mod index 9e910a541b..8061858727 100644 --- a/cli/cli/go.mod +++ b/cli/cli/go.mod @@ -29,7 +29,7 @@ require ( github.com/kurtosis-tech/kurtosis/metrics-library/golang v0.0.0 // Local dependency github.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409 github.com/manifoldco/promptui v0.9.0 - github.com/mattn/go-isatty v0.0.19 + github.com/mattn/go-isatty v0.0.20 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 @@ -45,9 +45,14 @@ require github.com/bazelbuild/buildtools v0.0.0-20221110131218-762712d8ce3f require ( github.com/briandowns/spinner v1.20.0 + github.com/cli/cli/v2 v2.42.1 + github.com/cli/go-gh/v2 v2.4.1-0.20231120145612-d32c104a9a25 + github.com/cli/oauth v1.0.1 github.com/compose-spec/compose-go v1.17.0 github.com/fatih/color v1.13.0 + github.com/go-git/go-git/v5 v5.11.0 github.com/google/go-github/v50 v50.2.0 + github.com/henvic/httpretty v0.1.3 github.com/joho/godotenv v1.5.1 github.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2 github.com/kurtosis-tech/kurtosis/cloud/api/golang v0.0.0 @@ -56,6 +61,7 @@ require ( github.com/kurtosis-tech/vscode-kurtosis/starlark-lsp v0.0.0-20230406131103-c466e04f1b89 github.com/mholt/archiver v3.1.1+incompatible github.com/xlab/treeprint v1.2.0 + github.com/zalando/go-keyring v0.2.3 golang.org/x/exp v0.0.0-20230905200255-921286631fa9 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 @@ -66,13 +72,20 @@ require ( require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/alessio/shellescape v1.4.1 // indirect + github.com/aymanbagabas/go-osc52 v1.0.3 // indirect github.com/bytedance/sonic v1.10.0-rc3 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect + github.com/cli/browser v1.3.0 // indirect + github.com/cli/safeexec v1.0.1 // indirect + github.com/cli/shurcooL-graphql v0.0.4 // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/containerd/containerd v1.7.2 // indirect github.com/containerd/typeurl/v2 v2.1.1 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/danieljoos/wincred v1.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa // indirect @@ -86,34 +99,42 @@ require ( github.com/gammazero/workerpool v1.1.2 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/gin-gonic/gin v1.9.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/swag v0.22.4 // indirect github.com/go-playground/validator/v10 v10.14.1 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.4.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0 // indirect github.com/kurtosis-tech/kurtosis/utils v0.0.0-20240104153602-385833de9d76 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/buildkit v0.12.4 // indirect @@ -122,6 +143,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect + github.com/muesli/termenv v0.13.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nwaples/rardecode v1.1.3 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect @@ -129,14 +151,19 @@ require ( github.com/pascaldekloe/name v1.0.1 // indirect github.com/pelletier/go-toml/v2 v2.0.9 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/rs/cors v1.9.0 // indirect github.com/segmentio/backo-go v1.0.0 // indirect github.com/segmentio/encoding v0.2.7 // indirect + github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278 // indirect + github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 // indirect github.com/smacker/go-tree-sitter v0.0.0-20230226123037-c459dbde1464 // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/stretchr/objx v0.5.0 // indirect + github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect @@ -156,21 +183,22 @@ require ( go.uber.org/multierr v1.7.0 // indirect go.uber.org/zap v1.20.0 // indirect golang.org/x/arch v0.4.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 // indirect + golang.org/x/mod v0.13.0 // indirect + golang.org/x/net v0.19.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sync v0.3.0 // indirect + golang.org/x/sync v0.4.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/segmentio/analytics-go.v3 v3.1.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect k8s.io/klog/v2 v2.90.1 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect nhooyr.io/websocket v1.8.7 // indirect diff --git a/cli/cli/go.sum b/cli/cli/go.sum index a0efc36cde..5cb753030d 100644 --- a/cli/cli/go.sum +++ b/cli/cli/go.sum @@ -17,12 +17,13 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -34,6 +35,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -45,6 +48,8 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aymanbagabas/go-osc52 v1.0.3 h1:DTwqENW7X9arYimJrPeGZcV0ln14sGMt3pHZspWD+Mg= +github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/bazelbuild/buildtools v0.0.0-20221110131218-762712d8ce3f h1:pkH5ds19YGNyq6CaDwioradmMA9XCMDhEN2jCgI8OF0= github.com/bazelbuild/buildtools v0.0.0-20221110131218-762712d8ce3f/go.mod h1:689QdV3hBP7Vo9dJMmzhoYIyo/9iMhEmHkJcnaPRCbo= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= @@ -59,7 +64,7 @@ github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBT github.com/briandowns/spinner v1.20.0 h1:GQq1Yf1KyzYT8CY19GzWrDKP6hYOFB6J72Ks7d8aO1U= github.com/briandowns/spinner v1.20.0/go.mod h1:TcwZHb7Wb6vn/+bcVv1UXEzaA4pLS7yznHlkY/HzH44= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0= @@ -84,8 +89,21 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/cli/browser v1.0.0/go.mod h1:IEWkHYbLjkhtjwwWlwTHW2lGxeS5gezEQBMLTwDHf5Q= +github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo= +github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk= +github.com/cli/cli/v2 v2.42.1 h1:LtgC7N46J9xdRhq9KNUUpowy41H4xjlBCmgcl4pw7H8= +github.com/cli/cli/v2 v2.42.1/go.mod h1:Jtsn9iQxcsIE6T9Aj88xSMFnaZP35rjkD+Cpr1QnbUg= +github.com/cli/go-gh/v2 v2.4.1-0.20231120145612-d32c104a9a25 h1:m2opPgNTaKx1QydI4NfGdZqiYkA/Kl9a7tsDSjHgWWg= +github.com/cli/go-gh/v2 v2.4.1-0.20231120145612-d32c104a9a25/go.mod h1:h3salfqqooVpzKmHp6aUdeNx62UmxQRpLbagFSHTJGQ= +github.com/cli/oauth v1.0.1 h1:pXnTFl/qUegXHK531Dv0LNjW4mLx626eS42gnzfXJPA= +github.com/cli/oauth v1.0.1/go.mod h1:qd/FX8ZBD6n1sVNQO3aIdRxeu5LGw9WhKnYhIIoC2A4= +github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= +github.com/cli/safeexec v1.0.1 h1:e/C79PbXF4yYTN/wauC4tviMxEV13BwljGj0N9j+N00= +github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= +github.com/cli/shurcooL-graphql v0.0.4 h1:6MogPnQJLjKkaXPyGqPRXOI2qCsQdqNfUY1QSJu2GuY= +github.com/cli/shurcooL-graphql v0.0.4/go.mod h1:3waN4u02FiZivIV+p1y4d0Jo1jc6BViMA73C+sZo2fk= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -106,8 +124,12 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= +github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= 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= @@ -138,6 +160,7 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= @@ -156,7 +179,7 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gammazero/deque v0.1.0 h1:f9LnNmq66VDeuAlSAapemq/U7hJ2jpIWa4c09q8Dlik= github.com/gammazero/deque v0.1.0/go.mod h1:KQw7vFau1hHuM8xmI9RbgKFbAsQFWmBpqQ2KenFLk6M= github.com/gammazero/workerpool v1.1.2 h1:vuioDQbgrz4HoaCi2q1HLlOXdpbap5AET7xu5/qj87g= @@ -170,6 +193,13 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -210,6 +240,8 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +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/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= @@ -221,6 +253,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -257,8 +291,8 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-github/v50 v50.2.0 h1:j2FyongEHlO9nxXLc+LP3wuBSVU9mVxfpdYUexMpIfk= github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q= @@ -272,6 +306,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -294,6 +330,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -314,6 +351,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/henvic/httpretty v0.1.3 h1:4A6vigjz6Q/+yAfTD4wqipCv+Px69C7Th/NhT0ApuU8= +github.com/henvic/httpretty v0.1.3/go.mod h1:UUEv7c2kHZ5SPQ51uS3wBpzPDibg2U3Y+IaXyHy5GBg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= @@ -324,6 +363,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= @@ -383,6 +424,8 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -401,12 +444,15 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 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.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +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-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU= github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= @@ -435,6 +481,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/muesli/termenv v0.13.0 h1:wK20DRpJdDX8b7Ek2QfhvqhRQFZ237RGRO0RQ/Iqdy0= +github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -460,7 +508,7 @@ github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -487,6 +535,8 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -522,11 +572,14 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 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/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -544,10 +597,14 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278 h1:kdEGVAV4sO46DPtb8k793jiecUEhaX9ixoIBt41HEGU= +github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278/go.mod h1:zqMwyHmnN/eDOZOdiTohqIUKUrTFX62PNlu7IJdu0q8= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 h1:17JxqqJY66GmZVHkmAsGEkcIu0oCe3AM420QDgGwZx0= +github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466/go.mod h1:9dIRpgIY7hVhoqfe0/FcYp0bpInZaT7dc3BYOprrIUE= github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= @@ -608,6 +665,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o 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/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8= +github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= @@ -638,6 +697,9 @@ github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63M github.com/yuin/goldmark v1.1.27/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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +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.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= @@ -698,6 +760,8 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -720,8 +784,10 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -749,8 +815,12 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY 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-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -766,8 +836,10 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -805,16 +877,24 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -822,6 +902,10 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -849,8 +933,10 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -926,12 +1012,14 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/segmentio/analytics-go.v3 v3.1.0 h1:UzxH1uaGZRpMKDhJyBz0pexz6yUoBU3x8bJsRk/HV6U= gopkg.in/segmentio/analytics-go.v3 v3.1.0/go.mod h1:4QqqlTlSSpVlWA9/9nDcPw+FkM2yv1NQoYjUbL9/JAw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/cli/cli/helpers/engine_manager/engine_existence_guarantor.go b/cli/cli/helpers/engine_manager/engine_existence_guarantor.go index a21f5992d4..c522476f86 100644 --- a/cli/cli/helpers/engine_manager/engine_existence_guarantor.go +++ b/cli/cli/helpers/engine_manager/engine_existence_guarantor.go @@ -3,6 +3,7 @@ package engine_manager import ( "context" "fmt" + "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/github_auth_store" "github.com/Masterminds/semver/v3" "github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context" @@ -77,6 +78,9 @@ type engineExistenceGuarantor struct { // Whether the engine's should run with the debug server to receive a remote debug connection shouldRunInDebugMode bool + + // token with git auth to override existing GitHub auth if there is any + githubAuthTokenOverride string } func newEngineExistenceGuarantorWithDefaultVersion( @@ -93,6 +97,8 @@ func newEngineExistenceGuarantorWithDefaultVersion( enclaveEnvVars string, allowedCORSOrigins *[]string, shouldRunInDebugMode bool, + githubAuthTokenOverride string, + ) *engineExistenceGuarantor { return newEngineExistenceGuarantorWithCustomVersion( ctx, @@ -109,6 +115,7 @@ func newEngineExistenceGuarantorWithDefaultVersion( enclaveEnvVars, allowedCORSOrigins, shouldRunInDebugMode, + githubAuthTokenOverride, ) } @@ -127,6 +134,7 @@ func newEngineExistenceGuarantorWithCustomVersion( enclaveEnvVars string, allowedCORSOrigins *[]string, shouldRunInDebugMode bool, + githubAuthTokenOverride string, ) *engineExistenceGuarantor { return &engineExistenceGuarantor{ ctx: ctx, @@ -145,6 +153,7 @@ func newEngineExistenceGuarantorWithCustomVersion( enclaveEnvVars: enclaveEnvVars, allowedCORSOrigins: allowedCORSOrigins, shouldRunInDebugMode: shouldRunInDebugMode, + githubAuthTokenOverride: githubAuthTokenOverride, } } @@ -164,6 +173,27 @@ func (guarantor *engineExistenceGuarantor) VisitStopped() error { maybeCloudUserId, maybeCloudInstanceId := metrics_cloud_user_instance_id_helper.GetMaybeCloudUserAndInstanceID() + var githubAuthToken string + // If override was provided, use it, else use existing GitHub auth if it exists + if guarantor.githubAuthTokenOverride != "" { + githubAuthToken = guarantor.githubAuthTokenOverride + } else { + githubAuthStore, err := github_auth_store.GetGitHubAuthStore() + if err != nil { + return stacktrace.Propagate(err, "An error occurred retrieving GitHub auth store.") + } + username, err := githubAuthStore.GetUser() + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting GitHub user.") + } + if username != "" { + githubAuthToken, err = githubAuthStore.GetAuthToken() + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting GitHub auth token for user: %v.", username) + } + } + } + var engineLaunchErr error if guarantor.imageVersionTag == defaultEngineImageVersionTag { _, _, engineLaunchErr = guarantor.engineServerLauncher.LaunchWithDefaultVersion( @@ -181,6 +211,7 @@ func (guarantor *engineExistenceGuarantor) VisitStopped() error { maybeCloudInstanceId, guarantor.allowedCORSOrigins, guarantor.shouldRunInDebugMode, + githubAuthToken, ) } else { _, _, engineLaunchErr = guarantor.engineServerLauncher.LaunchWithCustomVersion( @@ -199,6 +230,7 @@ func (guarantor *engineExistenceGuarantor) VisitStopped() error { maybeCloudInstanceId, guarantor.allowedCORSOrigins, guarantor.shouldRunInDebugMode, + githubAuthToken, ) } if engineLaunchErr != nil { diff --git a/cli/cli/helpers/engine_manager/engine_manager.go b/cli/cli/helpers/engine_manager/engine_manager.go index 7717e88c82..f1638f5bb1 100644 --- a/cli/cli/helpers/engine_manager/engine_manager.go +++ b/cli/cli/helpers/engine_manager/engine_manager.go @@ -176,7 +176,11 @@ func (manager *EngineManager) GetEngineStatus( } // StartEngineIdempotentlyWithDefaultVersion Starts an engine if one doesn't exist already, and returns a client to it -func (manager *EngineManager) StartEngineIdempotentlyWithDefaultVersion(ctx context.Context, logLevel logrus.Level, poolSize uint8) (kurtosis_engine_rpc_api_bindings.EngineServiceClient, func() error, error) { +func (manager *EngineManager) StartEngineIdempotentlyWithDefaultVersion( + ctx context.Context, + logLevel logrus.Level, + poolSize uint8, + githubAuthTokenOverride string) (kurtosis_engine_rpc_api_bindings.EngineServiceClient, func() error, error) { status, maybeHostMachinePortBinding, engineVersion, err := manager.GetEngineStatus(ctx) if err != nil { return nil, nil, stacktrace.Propagate(err, "An error occurred retrieving the Kurtosis engine status, which is necessary for creating a connection to the engine") @@ -197,6 +201,7 @@ func (manager *EngineManager) StartEngineIdempotentlyWithDefaultVersion(ctx cont manager.enclaveEnvVars, manager.allowedCORSOrigins, doNotStartTheEngineInDebugModeForDefaultVersion, + githubAuthTokenOverride, ) // TODO Need to handle the Kubernetes case, where a gateway needs to be started after the engine is started but // before we can return an EngineClient @@ -207,8 +212,14 @@ func (manager *EngineManager) StartEngineIdempotentlyWithDefaultVersion(ctx cont return engineClient, engineClientCloseFunc, nil } -// StartEngineIdempotentlyWithCustomVersion Starts an engine if one doesn't exist already, and returns a client to it -func (manager *EngineManager) StartEngineIdempotentlyWithCustomVersion(ctx context.Context, engineImageVersionTag string, logLevel logrus.Level, poolSize uint8, shouldStartInDebugMode bool) (kurtosis_engine_rpc_api_bindings.EngineServiceClient, func() error, error) { +// StartEngineIdempotentlyWithCustomVersion Starts an engine if one doesn't exist already, and returns a client to it TokenOverride string) (kurtosis_engine_rpc_api_bindings.EngineServiceClient, func() error, error) { +func (manager *EngineManager) StartEngineIdempotentlyWithCustomVersion( + ctx context.Context, + engineImageVersionTag string, + logLevel logrus.Level, + poolSize uint8, + shouldStartInDebugMode bool, + githubAuthTokenOverride string) (kurtosis_engine_rpc_api_bindings.EngineServiceClient, func() error, error) { status, maybeHostMachinePortBinding, engineVersion, err := manager.GetEngineStatus(ctx) if err != nil { return nil, nil, stacktrace.Propagate(err, "An error occurred retrieving the Kurtosis engine status, which is necessary for creating a connection to the engine") @@ -230,6 +241,7 @@ func (manager *EngineManager) StartEngineIdempotentlyWithCustomVersion(ctx conte manager.enclaveEnvVars, manager.allowedCORSOrigins, shouldStartInDebugMode, + githubAuthTokenOverride, ) engineClient, engineClientCloseFunc, err := manager.startEngineWithGuarantor(ctx, status, engineGuarantor) if err != nil { @@ -321,7 +333,14 @@ func (manager *EngineManager) StopEngineIdempotently(ctx context.Context) error // If no optionalVersionToUse is passed, then the new engine will take the default version, unless // restartEngineOnSameVersionIfAnyRunning is set to true in which case it will take the version of the currently // running engine -func (manager *EngineManager) RestartEngineIdempotently(ctx context.Context, logLevel logrus.Level, optionalVersionToUse string, restartEngineOnSameVersionIfAnyRunning bool, poolSize uint8, shouldStartInDebugMode bool) (kurtosis_engine_rpc_api_bindings.EngineServiceClient, func() error, error) { +func (manager *EngineManager) RestartEngineIdempotently( + ctx context.Context, + logLevel logrus.Level, + optionalVersionToUse string, + restartEngineOnSameVersionIfAnyRunning bool, + poolSize uint8, + shouldStartInDebugMode bool, + githubAuthTokenOverride string) (kurtosis_engine_rpc_api_bindings.EngineServiceClient, func() error, error) { var versionOfNewEngine string // We try to do our best to restart an engine on the same version the current on is on _, _, currentEngineVersion, err := manager.GetEngineStatus(ctx) @@ -346,9 +365,9 @@ func (manager *EngineManager) RestartEngineIdempotently(ctx context.Context, log var engineClientCloseFunc func() error var restartEngineErr error if versionOfNewEngine != defaultEngineVersion { - _, engineClientCloseFunc, restartEngineErr = manager.StartEngineIdempotentlyWithCustomVersion(ctx, versionOfNewEngine, logLevel, poolSize, shouldStartInDebugMode) + _, engineClientCloseFunc, restartEngineErr = manager.StartEngineIdempotentlyWithCustomVersion(ctx, versionOfNewEngine, logLevel, poolSize, shouldStartInDebugMode, githubAuthTokenOverride) } else { - _, engineClientCloseFunc, restartEngineErr = manager.StartEngineIdempotentlyWithDefaultVersion(ctx, logLevel, poolSize) + _, engineClientCloseFunc, restartEngineErr = manager.StartEngineIdempotentlyWithDefaultVersion(ctx, logLevel, poolSize, githubAuthTokenOverride) } if restartEngineErr != nil { return nil, nil, stacktrace.Propagate(restartEngineErr, "An error occurred starting a new engine") diff --git a/cli/cli/helpers/github_auth_store/github_auth_store.go b/cli/cli/helpers/github_auth_store/github_auth_store.go new file mode 100644 index 0000000000..51b7686450 --- /dev/null +++ b/cli/cli/helpers/github_auth_store/github_auth_store.go @@ -0,0 +1,361 @@ +package github_auth_store + +import ( + "errors" + "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/host_machine_directories" + "github.com/kurtosis-tech/stacktrace" + "github.com/sirupsen/logrus" + "github.com/zalando/go-keyring" + "os" + "sync" +) + +const ( + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // DO NOT CHANGE THIS VALUE + // Changing this value could leak tokens in a users keyring/make Kurtosis unable to retrieve/remove them. + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + kurtosisCliKeyringServiceName = "kurtosis-cli" + + githubAuthFilesPerms = 0644 +) + +var ( + // NOTE: This will be initialized exactly once (singleton pattern) + githubAuthStore GitHubAuthStore + once sync.Once + + NoTokenFound = errors.New("no token found for currently logged in user") +) + +// GitHubAuthStore stores information about a GitHub user that has authorized Kurtosis CLI to perform git operations on their behalf +// [username] is their GitHub username +// [authToken] is a scoped token that authorizes Kurtosis CLI on behalf of [username +type GitHubAuthStore interface { + // GetUser returns [username] of current user + // If no user exists, returns empty string + GetUser() (string, error) + + // GetAuthToken returns authToken for the user if they exist + // If [authToken] doesn't exist in system credential storage, attempts to retrieve token from plain text file + // Returns empty string if no user exists + // Returns NoTokenFound err if user exists but no [authToken] was found + GetAuthToken() (string, error) + + // SetUser sets current user to [username] and stores their [authToken] in system credential storage if it exists + // otherwise, stores [authToken] in plain text file + SetUser(username, authToken string) error + + // RemoveUser removes user and user's [authToken] from store, if a user exists + RemoveUser() error +} + +func GetGitHubAuthStore() (GitHubAuthStore, error) { + store, err := NewGitHubAuthStore() + if err != nil { + return nil, err + } + once.Do(func() { + // NOTE: We use a 'once' to initialize the GitHubAuthStore because it contains a mutex to guard + // the files, and we don't ever want multiple GitHubAuthStore instances in existence + githubAuthStore = store + }) + return githubAuthStore, nil +} + +type githubConfigStoreImpl struct { + *sync.RWMutex + + usernameFilePath, authTokenFilePath string +} + +func NewGitHubAuthStore() (GitHubAuthStore, error) { + usernameFilePath, err := host_machine_directories.GetGitHubUsernameFilePath() + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred getting the GitHub username filepath") + } + authTokenFilePath, err := host_machine_directories.GetGitHubAuthTokenFilePath() + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred getting the Github auth token filepath") + } + return &githubConfigStoreImpl{ + RWMutex: &sync.RWMutex{}, + usernameFilePath: usernameFilePath, + authTokenFilePath: authTokenFilePath, + }, nil +} + +func newGitHubAuthStoreForTesting(testUsernameFilePath, testAuthTokenFilePath string) GitHubAuthStore { + return &githubConfigStoreImpl{ + RWMutex: &sync.RWMutex{}, + usernameFilePath: testUsernameFilePath, + authTokenFilePath: testAuthTokenFilePath, + } +} + +func (store *githubConfigStoreImpl) GetUser() (string, error) { + store.RLock() + defer store.RUnlock() + + username, userExists, err := store.getUserAndIfTheyExist() + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred verifying if a user exists.") + } + if !userExists { + return "", nil + } + return username, nil +} + +func (store *githubConfigStoreImpl) GetAuthToken() (string, error) { + store.RLock() + defer store.RUnlock() + + username, userExists, err := store.getUserAndIfTheyExist() + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred verifying if a user exists.") + } + if !userExists { + return "", nil + } + + authToken, err := getAuthTokenFromKeyring(username) + if err == nil { + return authToken, nil + } + if err != nil && !errors.Is(err, keyring.ErrNotFound) { + return "", stacktrace.Propagate(err, "An error getting auth token from keyring for GitHub user: %v.", username) + } + logrus.Debugf("No auth token found in keyring for user '%v'\nFalling back to retrieving auth token from plain text file.", username) + githubAuthTokenFileExists, err := store.doesGitHubAuthTokenFileExist() + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred verifying if GitHub auth token file exists for GitHub user: %v.", username) + } + if !githubAuthTokenFileExists { + return "", NoTokenFound + } + authToken, err = store.getGitHubAuthTokenFromFile() + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred getting auth token from file for GitHub user: %v", username) + } + if authToken == "" { + return "", NoTokenFound + } + return authToken, nil +} + +func (store *githubConfigStoreImpl) SetUser(username, authToken string) error { + store.Lock() + defer store.Unlock() + + err := store.saveGitHubUsernameFile(username) + if err != nil { + return stacktrace.Propagate(err, "An error occurred saving '%v' to store.", username) + } + shouldUnsetGitHubUsername := true + defer func() { + if shouldUnsetGitHubUsername { + if err := store.removeGitHubUsernameFile(); err != nil { + logrus.Errorf("Error occurred removing GitHub username after setting it failed!!! GitHub auth could be in a bad state.") + } + } + }() + + err = store.setAuthToken(username, authToken) + if err != nil { + return stacktrace.Propagate(err, "An error occurred setting auth token in store for user: %v", username) + } + shouldUnsetAuthToken := true + defer func() { + if shouldUnsetAuthToken { + if err = store.removeAuthToken(username); err != nil { + logrus.Errorf("Error occurred removing GitHub auth token after setting it failed!!! GitHub auth could be in a bad state.") + } + } + }() + + shouldUnsetGitHubUsername = false + shouldUnsetAuthToken = false + return nil +} + +func (store *githubConfigStoreImpl) RemoveUser() error { + store.Lock() + defer store.Unlock() + + username, userExists, err := store.getUserAndIfTheyExist() + if err != nil { + return stacktrace.Propagate(err, "An error occurred verifying if a user exists.") + } + if !userExists { + return nil + } + + err = store.removeAuthToken(username) + if err != nil { + return stacktrace.Propagate(err, "An error occurred removing user '%v' token from store.", username) + } + + err = store.removeGitHubUsernameFile() + if err != nil { + return stacktrace.Propagate(err, "An error occurred removing GitHub user '%v' from store", username) + } + + return nil +} + +func (store *githubConfigStoreImpl) getUserAndIfTheyExist() (string, bool, error) { + userExists, err := store.doesGitHubUsernameFileExist() + if err != nil { + return "", false, stacktrace.Propagate(err, "An error occurred discovering if user exists.") + } + if !userExists { + return "", false, nil + } + username, err := store.getGitHubUsernameFromFile() + if err != nil { + return "", false, stacktrace.Propagate(err, "An error occurred getting user from store.") + } + if username == "" { + return "", false, nil + } + return username, true, nil +} + +// setAuthToken attempts to set the git auth token for username +// Will attempt to store in secure system credential storage, but if no secure storage is found will resort to storing in a plain text file +func (store *githubConfigStoreImpl) setAuthToken(username, authToken string) error { + err := setAuthTokenInKeyring(username, authToken) + if err == nil { + return nil + } + logrus.Debugf("An error occurred setting GitHub auth token in keyring: %v\nFalling back to setting token in plain text file.", err) + err = store.saveGitHubAuthTokenFile(authToken) + if err != nil { + return stacktrace.Propagate(err, "An error occurred attempting to store GitHub auth token in plain text file after failing to store in keyring.") + } + return nil +} + +func (store *githubConfigStoreImpl) removeAuthToken(username string) error { + err := removeAuthTokenFromKeyring(username) + if err == nil { + return nil + } + logrus.Debugf("An error occurred removing GitHub auth token in keyring: %v\nAssuming token is in plain text file and removing from there.", err) + err = store.removeGitHubAuthTokenFile() + if err != nil { + return stacktrace.Propagate(err, "An error occurred removing GitHub auth token from plain text file after failing to remove from keyring.") + } + return nil +} + +func (store *githubConfigStoreImpl) doesGitHubUsernameFileExist() (bool, error) { + _, err := os.Stat(store.usernameFilePath) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, stacktrace.Propagate(err, "An error occurred verifying if filepath '%v' exists", store.usernameFilePath) + } + return true, nil +} + +func (store *githubConfigStoreImpl) getGitHubUsernameFromFile() (string, error) { + logrus.Debugf("Github username filepath: '%v'", store.usernameFilePath) + fileContentBytes, err := os.ReadFile(store.usernameFilePath) + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred reading GitHub username file") + } + fileContentStr := string(fileContentBytes) + return fileContentStr, nil +} + +func (store *githubConfigStoreImpl) saveGitHubUsernameFile(username string) error { + fileContent := []byte(username) + logrus.Debugf("Saving git username in file...") + err := os.WriteFile(store.usernameFilePath, fileContent, githubAuthFilesPerms) + if err != nil { + return stacktrace.Propagate(err, "An error occurred writing GitHub username to file '%v'", store.usernameFilePath) + } + logrus.Debugf("Saved GitHub username file") + return nil +} + +func (store *githubConfigStoreImpl) removeGitHubUsernameFile() error { + logrus.Debugf("Removing git username in file...") + err := os.Remove(store.usernameFilePath) + if err != nil { + return stacktrace.Propagate(err, "An error occurred removing GitHub username file '%v'", store.usernameFilePath) + } + logrus.Debugf("Removed Github username file") + return nil +} + +func (store *githubConfigStoreImpl) doesGitHubAuthTokenFileExist() (bool, error) { + _, err := os.Stat(store.authTokenFilePath) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, stacktrace.Propagate(err, "An error occurred verifying if filepath '%v' exists", store.authTokenFilePath) + } + return true, nil +} + +func (store *githubConfigStoreImpl) getGitHubAuthTokenFromFile() (string, error) { + fileContentBytes, err := os.ReadFile(store.authTokenFilePath) + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred reading GitHub auth token file") + } + fileContentStr := string(fileContentBytes) + return fileContentStr, nil +} + +func (store *githubConfigStoreImpl) saveGitHubAuthTokenFile(authToken string) error { + fileContent := []byte(authToken) + logrus.Debugf("Saving GitHub auth token in file...") + err := os.WriteFile(store.authTokenFilePath, fileContent, githubAuthFilesPerms) + if err != nil { + return stacktrace.Propagate(err, "An error occurred writing GitHub auth token to file '%v'", store.authTokenFilePath) + } + logrus.Debugf("Saved GitHub auth token") + return nil +} + +func (store *githubConfigStoreImpl) removeGitHubAuthTokenFile() error { + logrus.Debugf("Removing GitHub auth token file...") + err := os.Remove(store.authTokenFilePath) + if err != nil { + return stacktrace.Propagate(err, "An error occurred removing GitHub auth token file '%v'", store.authTokenFilePath) + } + logrus.Debugf("Removed GitHub auth token file") + return nil +} + +func getAuthTokenFromKeyring(username string) (string, error) { + authToken, err := keyring.Get(kurtosisCliKeyringServiceName, username) + if err != nil && errors.Is(err, keyring.ErrNotFound) { + return "", err // don't wrap so this specific err can be detected + } + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred retrieving token for '%v' from keyring", username) + } + return authToken, nil +} + +func setAuthTokenInKeyring(username, authToken string) error { + err := keyring.Set(kurtosisCliKeyringServiceName, username, authToken) + if err != nil { + return stacktrace.Propagate(err, "An error occurred setting GitHub auth token for user '%v' in keyring.", username) + } + return nil +} + +func removeAuthTokenFromKeyring(username string) error { + err := keyring.Delete(kurtosisCliKeyringServiceName, username) + if err != nil { + return stacktrace.Propagate(err, "An error occurred removing GitHub auth token for user '%v' from keyring", username) + } + return nil +} diff --git a/cli/cli/helpers/github_auth_store/github_auth_store_test.go b/cli/cli/helpers/github_auth_store/github_auth_store_test.go new file mode 100644 index 0000000000..9d2ee9d683 --- /dev/null +++ b/cli/cli/helpers/github_auth_store/github_auth_store_test.go @@ -0,0 +1,297 @@ +package github_auth_store + +import ( + "github.com/stretchr/testify/require" + "github.com/zalando/go-keyring" + "os" + "testing" +) + +const ( + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //DO NOT CHANGE THIS VALUE + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + expectedKeyringServiceName = "kurtosis-cli" + + tempFileDir = "" + tempUsernameFileNamePattern = "github-username" + tempAuthTokenFileNamePattern = "github-token" +) + +// The keyring service name in this package has to be always "kurtosis-cli" +// so we control that it does not change +func TestKeyringServiceNameDoesNotChange(t *testing.T) { + require.Equal(t, expectedKeyringServiceName, kurtosisCliKeyringServiceName) +} + +func TestGetUserReturnsEmptyStringIfNoUserExists(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + actualUsername, err := store.GetUser() + require.NoError(t, err) + require.Empty(t, actualUsername) +} + +func TestGetUserReturnsUser(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + expectedUsername := "john123" + _, err = tempUsernameFile.Write([]byte(expectedUsername)) + require.NoError(t, err) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + actualUsername, err := store.GetUser() + require.NoError(t, err) + require.Equal(t, expectedUsername, actualUsername) +} + +func TestGetAuthTokenGetsTokenFromKeyring(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + expectedUsername := "john123" + expectedToken := "token" + _, err = tempUsernameFile.Write([]byte(expectedUsername)) + require.NoError(t, err) + keyring.MockInit() // changes the underlying keyring to an in memory keyring for testing + err = keyring.Set(kurtosisCliKeyringServiceName, expectedUsername, expectedToken) + require.NoError(t, err) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + actualToken, err := store.GetAuthToken() + require.NoError(t, err) + require.Equal(t, expectedToken, actualToken) +} + +func TestGetAuthTokenReturnsEmptyStringIfNoUserExists(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + actualToken, err := store.GetAuthToken() + require.NoError(t, err) + require.Empty(t, actualToken) +} + +func TestGetAuthTokenGetsTokenFromFile(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + username := "john123" + expectedToken := "token" + _, err = tempUsernameFile.Write([]byte(username)) + require.NoError(t, err) + _, err = tempAuthTokenFile.Write([]byte(expectedToken)) + require.NoError(t, err) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + actualToken, err := store.GetAuthToken() + require.NoError(t, err) + require.Equal(t, expectedToken, actualToken) +} + +func TestGetAuthTokenReturnsNoTokenFoundIfUserExistsWithNoToken(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + _, err = tempUsernameFile.Write([]byte("john123")) + require.NoError(t, err) + keyring.MockInit() + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + _, err = store.GetAuthToken() + require.ErrorIs(t, err, NoTokenFound) +} + +func TestSetUser(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + expectedUsername := "john123" + expectedAuthToken := "password" + keyring.MockInit() + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + currentUser, err := store.GetUser() + require.NoError(t, err) + require.Empty(t, currentUser) + + err = store.SetUser(expectedUsername, expectedAuthToken) + require.NoError(t, err) + + actualUsername, err := store.GetUser() + require.NoError(t, err) + require.Equal(t, expectedUsername, actualUsername) + + actualAuthToken, err := store.GetAuthToken() + require.NoError(t, err) + require.Equal(t, expectedAuthToken, actualAuthToken) +} + +func TestSetUserOverwritesExistingUser(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + oldUser := "john123" + oldToken := "password" + _, err = tempUsernameFile.Write([]byte(oldUser)) + require.NoError(t, err) + keyring.MockInit() + err = keyring.Set(kurtosisCliKeyringServiceName, oldUser, oldToken) + require.NoError(t, err) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + currentUser, err := store.GetUser() + require.NoError(t, err) + require.Equal(t, oldUser, currentUser) + + newUser := "tim" + newToken := "wordpass" + err = store.SetUser(newUser, newToken) + require.NoError(t, err) + + actualNewUser, err := store.GetUser() + require.NoError(t, err) + require.Equal(t, newUser, actualNewUser) + + actualNewToken, err := store.GetAuthToken() + require.NoError(t, err) + require.Equal(t, newToken, actualNewToken) +} + +func TestRemoveUserIsNoOpIfNoUserExists(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + err = store.RemoveUser() + require.NoError(t, err) +} + +func TestRemoveUserWithTokenInKeyring(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + expectedUsername := "john123" + expectedToken := "token" + _, err = tempUsernameFile.Write([]byte(expectedUsername)) + require.NoError(t, err) + keyring.MockInit() + err = keyring.Set(kurtosisCliKeyringServiceName, expectedUsername, expectedToken) + require.NoError(t, err) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + err = store.RemoveUser() + require.NoError(t, err) + + username, err := store.GetUser() + require.NoError(t, err) + require.Empty(t, username) + + authToken, err := store.GetAuthToken() + require.NoError(t, err) + require.Empty(t, authToken) +} + +func TestRemoveUserWithTokenInFile(t *testing.T) { + // setup mock GitHub store + tempUsernameFile, err := os.CreateTemp(tempFileDir, tempUsernameFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempUsernameFile.Name()) + tempAuthTokenFile, err := os.CreateTemp(tempFileDir, tempAuthTokenFileNamePattern) + require.NoError(t, err) + defer os.Remove(tempAuthTokenFile.Name()) + + expectedUsername := "john123" + expectedToken := "token" + _, err = tempUsernameFile.Write([]byte(expectedUsername)) + require.NoError(t, err) + _, err = tempAuthTokenFile.Write([]byte(expectedToken)) + require.NoError(t, err) + + // run test + store := newGitHubAuthStoreForTesting(tempUsernameFile.Name(), tempAuthTokenFile.Name()) + + err = store.RemoveUser() + require.NoError(t, err) + + username, err := store.GetUser() + require.NoError(t, err) + require.Empty(t, username) + + authToken, err := store.GetAuthToken() + require.NoError(t, err) + require.Empty(t, authToken) +} diff --git a/cli/cli/helpers/host_machine_directories/host_machine_directories.go b/cli/cli/helpers/host_machine_directories/host_machine_directories.go index 1222b28f51..d78a53dbb9 100644 --- a/cli/cli/helpers/host_machine_directories/host_machine_directories.go +++ b/cli/cli/helpers/host_machine_directories/host_machine_directories.go @@ -17,6 +17,9 @@ const ( metricsUserIDFilename = "metrics-user-id" + githubUsernameFilename = "github-username" + githubAuthTokenFilename = "github-auth-token" + userSendMetricsElection = "user-send-metrics-election" LastPesteredUserAboutOldVersionFilename = "last-pestered-user-about-old-version" @@ -147,6 +150,24 @@ func GetPortalPidFilePath() (string, error) { return portalPidFilePath, nil } +func GetGitHubUsernameFilePath() (string, error) { + xdgRelFilepath := getRelativeFilepathForXDG(githubUsernameFilename) + githubUsernameFilePath, err := xdg.StateFile(xdgRelFilepath) + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred getting Kurtosis GitHub username file path using '%s'", xdgRelFilepath) + } + return githubUsernameFilePath, nil +} + +func GetGitHubAuthTokenFilePath() (string, error) { + xdgRelFilepath := getRelativeFilepathForXDG(githubAuthTokenFilename) + githubAuthTokenFilePath, err := xdg.StateFile(xdgRelFilepath) + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred getting Kurtosis GitHub auth token file path using '%s'", xdgRelFilepath) + } + return githubAuthTokenFilePath, nil +} + // ==================================================================================================== // // Private Helper Functions diff --git a/cli/cli/helpers/metrics_user_id_store/metrics_user_id_store.go b/cli/cli/helpers/metrics_user_id_store/metrics_user_id_store.go index a64d801df8..bfdbc60a6a 100644 --- a/cli/cli/helpers/metrics_user_id_store/metrics_user_id_store.go +++ b/cli/cli/helpers/metrics_user_id_store/metrics_user_id_store.go @@ -58,7 +58,7 @@ func (store *MetricsUserIDStore) GetUserID() (string, error) { } else { userID, err = machineid.ProtectedID(applicationID) if err != nil { - return "", stacktrace.Propagate(err, "An error occurred generating anonimazed user ID") + return "", stacktrace.Propagate(err, "An error occurred generating anonymized user ID") } if err = store.saveMetricsUserIdFile(userID); err != nil { return "", stacktrace.Propagate(err, "An error occurred saving metrics user id in file") diff --git a/cli/cli/helpers/oauth/oauth.go b/cli/cli/helpers/oauth/oauth.go new file mode 100644 index 0000000000..2a4c940a75 --- /dev/null +++ b/cli/cli/helpers/oauth/oauth.go @@ -0,0 +1,168 @@ +package oauth + +import ( + "bufio" + "fmt" + "github.com/cli/cli/v2/api" + gitbrowser "github.com/cli/go-gh/v2/pkg/browser" + "github.com/cli/oauth" + "io" + "net/http" + "net/url" + "os" +) + +var ( + // The "Kurtosis CLI" OAuth app client id and secrets + + // According to GitHub, it's okay to embed the client id and secret as pointed out here: https://github.com/cli/oauth/issues/1#issuecomment-754713746 + oauthClientID = "ff28fd26dcaf1be48c45" + + // secret is actually not needed to retrieve the token, so we leave it empty + oauthClientSecret = "" + + isInteractive = true + oauthHost = "github.com" + emptyNotice = "" + defaultLauncher = "" +) + +var ( + browser = *gitbrowser.New(defaultLauncher, os.Stdout, os.Stderr) +) + +type OAuth interface { + AuthFlow() (string, string, error) +} + +// Retrieves a long-lived OAuth token from a GitHub user that authorizes Kurtosis CLI +// Returns the GitHub username, authToken or an error +func AuthFlow() (string, string, error) { + httpClient := &http.Client{} // nolint: exhaustruct + + minimumScopes := []string{"repo", "read:org", "gist"} + + callbackURI := "http://127.0.0.1/callback" + flow := &oauth.Flow{ // nolint: exhaustruct + Host: oauth.GitHubHost(fmt.Sprintf("https://%s/", oauthHost)), + ClientID: oauthClientID, + ClientSecret: oauthClientSecret, + CallbackURI: callbackURI, + Scopes: minimumScopes, + DisplayCode: func(code, verificationURL string) error { + fmt.Fprintf(os.Stdout, "First copy your one-time code: %s\n", code) + return nil + }, + BrowseURL: func(authURL string) error { + if u, err := url.Parse(authURL); err == nil { + if u.Scheme != "http" && u.Scheme != "https" { + return fmt.Errorf("invalid URL: %s", authURL) + } + } else { + return err + } + + if !isInteractive { + fmt.Fprintf(os.Stdout, "%s to continue in your web browser: %s\n", "Open this URL", authURL) + return nil + } + + fmt.Fprintf(os.Stdout, "%s to open %s in your browser... ", "Press Enter", oauthHost) + _ = waitForEnter(os.Stdin) + + if err := browser.Browse(authURL); err != nil { + fmt.Fprintf(os.Stdout, "%s Failed opening a web browser at %s\n", "!", authURL) + fmt.Fprintf(os.Stdout, " %s\n", err) + fmt.Fprint(os.Stdout, " Please try entering the URL in your browser manually\n") + } + return nil + }, + WriteSuccessHTML: func(w io.Writer) { + fmt.Fprint(w, oauthSuccessPage) + }, + HTTPClient: httpClient, + Stdin: os.Stdin, + Stdout: os.Stdout, + } + + fmt.Fprintln(os.Stdout, emptyNotice) + + token, err := flow.DetectFlow() + if err != nil { + return "", "", err + } + + userLogin, err := getViewer(oauthHost, token.Token, os.Stderr) + if err != nil { + return "", "", err + } + + return token.Token, userLogin, nil +} + +type cfg struct { + token string +} + +func (c cfg) ActiveToken(hostname string) (string, string) { + return c.token, "oauth_token" +} + +func getViewer(hostname, token string, logWriter io.Writer) (string, error) { + opts := api.HTTPClientOptions{ // nolint: exhaustruct + Config: cfg{token: token}, + Log: logWriter, + } + client, err := api.NewHTTPClient(opts) + if err != nil { + return "", err + } + return api.CurrentLoginName(api.NewClientFromHTTP(client), hostname) +} + +func waitForEnter(r io.Reader) error { + scanner := bufio.NewScanner(r) + scanner.Scan() + return scanner.Err() +} + +const oauthSuccessPage = ` + + +Success: GitHub CLI + + + +
+

Successfully authenticated Kurtosis CLI

+

You may now close this tab and return to the terminal.

+
+ +` diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/consts/consts.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/consts/consts.go index d2ede4273b..a3210874ea 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/consts/consts.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/consts/consts.go @@ -31,6 +31,8 @@ const ( //The Docker network name where all the containers in the engine and logs service context will be added NameOfNetworkToStartEngineAndLogServiceContainersIn = "bridge" HttpApplicationProtocol = "http" + + GitHubAuthStorageDirPath = "/kurtosis-data/github-auth/" ) // This maps a Docker container's status to a binary "is the container considered running?" determiner diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend.go index ed9c68ee64..7632be76aa 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend.go @@ -111,6 +111,7 @@ func (backend *DockerKurtosisBackend) CreateEngine( grpcPortNum uint16, envVars map[string]string, shouldStartInDebugMode bool, + gitAuthToken string, ) ( *engine.Engine, error, @@ -121,9 +122,10 @@ func (backend *DockerKurtosisBackend) CreateEngine( imageVersionTag, grpcPortNum, envVars, + shouldStartInDebugMode, + gitAuthToken, backend.dockerManager, backend.objAttrsProvider, - shouldStartInDebugMode, ) } @@ -591,3 +593,22 @@ func (backend *DockerKurtosisBackend) getEnclaveDataVolumeByEnclaveUuid(ctx cont volume := foundVolumes[0] return volume.Name, nil } + +// Guaranteed to either return a GitHub auth storage volume name or throw an error +func (backend *DockerKurtosisBackend) getGitHubAuthStorageVolume(ctx context.Context) (string, error) { + volumeSearchLabels := map[string]string{ + docker_label_key.VolumeTypeDockerLabelKey.GetString(): label_value_consts.GitHubAuthStorageVolumeTypeDockerLabelValue.GetString(), + } + foundVolumes, err := backend.dockerManager.GetVolumesByLabels(ctx, volumeSearchLabels) + if err != nil { + return "", stacktrace.Propagate(err, "An error occurred getting GitHub auth storage volumes matching labels '%+v'", volumeSearchLabels) + } + if len(foundVolumes) > 1 { + return "", stacktrace.NewError("Found multiple GitHub auth storage volumes. This should never happen") + } + if len(foundVolumes) == 0 { + return "", stacktrace.NewError("No GitHub auth storage volume found.") + } + volume := foundVolumes[0] + return volume.Name, nil +} diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_api_container_functions.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_api_container_functions.go index bfbf53d0a2..4f7d670833 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_api_container_functions.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_api_container_functions.go @@ -72,6 +72,11 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer( return nil, stacktrace.Propagate(err, "An error occurred getting the enclave data volume for enclave '%v'", enclaveUuid) } + githubAuthStorageVolumeName, err := backend.getGitHubAuthStorageVolume(ctx) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred getting the GitHub auth storage volume name.") + } + // Get the Docker network ID where we'll start the new API container enclaveNetwork, err := backend.getEnclaveNetworkByEnclaveUuid(ctx, enclaveUuid) if err != nil { @@ -187,7 +192,8 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer( } volumeMounts := map[string]string{ - enclaveDataVolumeName: enclaveDataVolumeDirpath, + enclaveDataVolumeName: enclaveDataVolumeDirpath, + githubAuthStorageVolumeName: consts.GitHubAuthStorageDirPath, } labelStrs := map[string]string{} diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/create_engine.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/create_engine.go index b4986f9d69..c3aad229f4 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/create_engine.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/create_engine.go @@ -3,6 +3,7 @@ package engine_functions import ( "context" "fmt" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/github_auth_storage_creator" "time" "github.com/docker/go-connections/nat" @@ -30,8 +31,7 @@ const ( engineDebugServerPort = 50102 // in ClI this is 50101 and 50103 for the APIC maxWaitForEngineAvailabilityRetries = 10 timeBetweenWaitForEngineAvailabilityRetries = 1 * time.Second - logsStorageDirpath = "/var/log/kurtosis/" - removeLogsWaitHours = 6 * time.Hour + logsStorageDirPath = "/var/log/kurtosis/" ) func CreateEngine( @@ -40,9 +40,10 @@ func CreateEngine( imageVersionTag string, grpcPortNum uint16, envVars map[string]string, + shouldStartInDebugMode bool, + gitAuthToken string, dockerManager *docker_manager.DockerManager, objAttrsProvider object_attributes_provider.DockerObjectAttributesProvider, - shouldStartInDebugMode bool, ) ( *engine.Engine, error, @@ -239,13 +240,34 @@ func CreateEngine( usedPorts[debugServerDockerPort] = docker_manager.NewManualPublishingSpec(uint16(engineDebugServerPort)) } + // Configure GitHub Auth by writing the provided token to a volume that's accessible by the engine + githubAuthStorageVolObjAttrs, err := objAttrsProvider.ForGitHubAuthStorageVolume() + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred retrieving object attributes for GitHub auth storage.") + } + githubAuthStorageVolNameStr := githubAuthStorageVolObjAttrs.GetName().GetString() + githubAuthStorageVolLabelStrs := map[string]string{} + for labelKey, labelValue := range githubAuthStorageVolObjAttrs.GetLabels() { + githubAuthStorageVolLabelStrs[labelKey.GetString()] = labelValue.GetString() + } + // This volume is created idempotently (like logs storage volume) and just write the token to the file everytime the engine starts + if err = dockerManager.CreateVolume(ctx, githubAuthStorageVolNameStr, githubAuthStorageVolLabelStrs); err != nil { + return nil, stacktrace.Propagate(err, "An error occurred creating GitHub auth storage volume.") + } + githubAuthStorageCreator := github_auth_storage_creator.NewGitHubAuthStorageCreator(gitAuthToken) + err = githubAuthStorageCreator.CreateGitHubAuthStorage(ctx, targetNetworkId, githubAuthStorageVolNameStr, consts.GitHubAuthStorageDirPath, dockerManager) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred creating GitHub auth storage.") + } + bindMounts := map[string]string{ // Necessary so that the engine server can interact with the Docker engine consts.DockerSocketFilepath: consts.DockerSocketFilepath, } volumeMounts := map[string]string{ - logsStorageVolNameStr: logsStorageDirpath, + logsStorageVolNameStr: logsStorageDirPath, + githubAuthStorageVolNameStr: consts.GitHubAuthStorageDirPath, } if serverArgs.OnBastionHost { diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/github_auth_storage_creator/github_auth_storage_creator.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/github_auth_storage_creator/github_auth_storage_creator.go new file mode 100644 index 0000000000..6fb2290a2a --- /dev/null +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/github_auth_storage_creator/github_auth_storage_creator.go @@ -0,0 +1,153 @@ +package github_auth_storage_creator + +import ( + "bytes" + "context" + "fmt" + "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_manager" + "github.com/kurtosis-tech/stacktrace" + "github.com/sirupsen/logrus" + "time" +) + +const ( + // We use this image and version because we already are using this in other projects so there is a high probability + // that the image is in the local machine's cache + creatorContainerImage = "alpine:3.17" + creatorContainerName = "kurtosis-github-auth-storage-creator" + + shBinaryFilepath = "/bin/sh" + shCmdFlag = "-c" + printfCmdName = "printf" + + authStorageCreationSuccessExitCode = 0 + + authStorageCreationCmdMaxRetries = 2 + authStorageCreationCmdDelayInRetries = 200 * time.Millisecond + + authTokenFilename = "token.txt" + + sleepSeconds = 1800 +) + +type GitHubAuthStorageCreator struct { + token string +} + +func NewGitHubAuthStorageCreator(token string) *GitHubAuthStorageCreator { + return &GitHubAuthStorageCreator{token: token} +} + +func (creator *GitHubAuthStorageCreator) CreateGitHubAuthStorage( + ctx context.Context, + targetNetworkId string, + volumeName string, + githubAuthStorageDirPath string, + dockerManager *docker_manager.DockerManager, +) error { + entrypointArgs := []string{ + shBinaryFilepath, + shCmdFlag, + fmt.Sprintf("sleep %v", sleepSeconds), + } + + volumeMounts := map[string]string{ + volumeName: githubAuthStorageDirPath, + } + + createAndStartArgs := docker_manager.NewCreateAndStartContainerArgsBuilder( + creatorContainerImage, + creatorContainerName, + targetNetworkId, + ).WithEntrypointArgs( + entrypointArgs, + ).WithVolumeMounts( + volumeMounts, + ).Build() + + containerId, _, err := dockerManager.CreateAndStartContainer(ctx, createAndStartArgs) + if err != nil { + return stacktrace.Propagate(err, "An error occurred starting the GitHub Auth Storage Creator container with these args '%+v'", createAndStartArgs) + } + //The killing step has to be executed always in the success and also in the failed case + defer func() { + if err = dockerManager.RemoveContainer(context.Background(), containerId); err != nil { + logrus.Errorf( + "Launching the GitHub Auth Storage Creator container with container ID '%v' didn't complete successfully so we "+ + "tried to remove the container we started, but doing so exited with an error:\n%v", + containerId, + err) + logrus.Errorf("ACTION REQUIRED: You'll need to manually remove the container with ID '%v'!!!!!!", containerId) + } + }() + + if err := creator.storeTokenInVolume( + ctx, + dockerManager, + containerId, + authStorageCreationCmdMaxRetries, + authStorageCreationCmdDelayInRetries, + githubAuthStorageDirPath, + ); err != nil { + return stacktrace.Propagate(err, "An error occurred creating GitHub auth storage in volume.") + } + + return nil +} + +func (creator *GitHubAuthStorageCreator) storeTokenInVolume( + ctx context.Context, + dockerManager *docker_manager.DockerManager, + containerId string, + maxRetries uint, + timeBetweenRetries time.Duration, + githubAuthStorageDirPath string, +) error { + commandStr := fmt.Sprintf( + "%v '%v' > %v", + printfCmdName, + creator.token, + fmt.Sprintf("%s/%s", githubAuthStorageDirPath, authTokenFilename), + ) + + execCmd := []string{ + shBinaryFilepath, + shCmdFlag, + commandStr, + } + for i := uint(0); i < maxRetries; i++ { + outputBuffer := &bytes.Buffer{} + exitCode, err := dockerManager.RunExecCommand(ctx, containerId, execCmd, outputBuffer) + if err == nil { + if exitCode == authStorageCreationSuccessExitCode { + logrus.Debugf("The GitHub auth token was successfully added into the volume.") + return nil + } + logrus.Debugf( + "GitHub auth storage creation command '%v' returned without a Docker error, but exited with non-%v exit code '%v' and logs:\n%v", + commandStr, + authStorageCreationSuccessExitCode, + exitCode, + outputBuffer.String(), + ) + } else { + logrus.Debugf( + "GitHub auth storage creation command '%v' experienced a Docker error:\n%v", + commandStr, + err, + ) + } + + // Tiny optimization to not sleep if we're not going to run the loop again + if i < maxRetries { + time.Sleep(timeBetweenRetries) + } + } + + return stacktrace.NewError( + "The GitHub auth storage creation didn't return success (as measured by the command '%v') even after retrying %v times with %v between retries", + commandStr, + maxRetries, + timeBetweenRetries, + ) +} diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/stop_engines.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/stop_engines.go index b6050fbc7b..67c0ae8f05 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/stop_engines.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/engine_functions/stop_engines.go @@ -2,7 +2,6 @@ package engine_functions import ( "context" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/logs_aggregator_functions" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/reverse_proxy_functions" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_impls/docker/docker_manager" @@ -14,8 +13,7 @@ import ( func StopEngines( ctx context.Context, filters *engine.EngineFilters, - dockerManager *docker_manager.DockerManager, -) ( + dockerManager *docker_manager.DockerManager) ( resultSuccessfulEngineGuids map[engine.EngineGUID]bool, resultErroredEngineGuids map[engine.EngineGUID]error, resultErr error, diff --git a/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/label_value_consts/label_value_consts.go b/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/label_value_consts/label_value_consts.go index 9b830cf813..c30e9d1a46 100644 --- a/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/label_value_consts/label_value_consts.go +++ b/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/label_value_consts/label_value_consts.go @@ -27,6 +27,7 @@ const ( persistentDirectoryVolumeTypeLabelValueStr = "persistent-directory" logsStorageVolumeTypeLabelValueStr = "kurtosis-logs-storage" logsCollectorVolumeTypeLabelValueStr = "logs-collector-data" + githubAuthStorageVolumeTypeLabelValueStr = "github-auth-storage" ) // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DO NOT CHANGE THESE VALUES !!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -52,3 +53,4 @@ var FilesArtifactExpansionVolumeTypeDockerLabelValue = docker_label_value.MustCr var PersistentDirectoryVolumeTypeDockerLabelValue = docker_label_value.MustCreateNewDockerLabelValue(persistentDirectoryVolumeTypeLabelValueStr) var LogsStorageVolumeTypeDockerLabelValue = docker_label_value.MustCreateNewDockerLabelValue(logsStorageVolumeTypeLabelValueStr) var LogsCollectorVolumeTypeDockerLabelValue = docker_label_value.MustCreateNewDockerLabelValue(logsCollectorVolumeTypeLabelValueStr) +var GitHubAuthStorageVolumeTypeDockerLabelValue = docker_label_value.MustCreateNewDockerLabelValue(githubAuthStorageVolumeTypeLabelValueStr) diff --git a/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/object_attributes_provider.go b/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/object_attributes_provider.go index a0691ad4e8..5c9af7fada 100644 --- a/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/object_attributes_provider.go +++ b/container-engine-lib/lib/backend_impls/docker/object_attributes_provider/object_attributes_provider.go @@ -17,11 +17,12 @@ import ( ) const ( - engineServerNamePrefix = "kurtosis-engine" - logsAggregatorName = "kurtosis-logs-aggregator" - logsStorageVolumeName = "kurtosis-logs-storage" - engineRESTAPIPortStr = "engine-rest-api" - reverseProxyNamePrefix = "kurtosis-reverse-proxy" + engineServerNamePrefix = "kurtosis-engine" + logsAggregatorName = "kurtosis-logs-aggregator" + logsStorageVolumeName = "kurtosis-logs-storage" + githubAuthStorageVolumeName = "kurtosis-github-auth-storage" + engineRESTAPIPortStr = "engine-rest-api" + reverseProxyNamePrefix = "kurtosis-reverse-proxy" ) type DockerObjectAttributesProvider interface { @@ -36,6 +37,7 @@ type DockerObjectAttributesProvider interface { ForLogsAggregator() (DockerObjectAttributes, error) ForLogsStorageVolume() (DockerObjectAttributes, error) ForReverseProxy(engineGuid engine.EngineGUID) (DockerObjectAttributes, error) + ForGitHubAuthStorageVolume() (DockerObjectAttributes, error) } func GetDockerObjectAttributesProvider() DockerObjectAttributesProvider { @@ -153,6 +155,23 @@ func (provider *dockerObjectAttributesProviderImpl) ForLogsStorageVolume() (Dock return objectAttributes, nil } +func (provider *dockerObjectAttributesProviderImpl) ForGitHubAuthStorageVolume() (DockerObjectAttributes, error) { + name, err := docker_object_name.CreateNewDockerObjectName(githubAuthStorageVolumeName) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred creating a Docker object name object from string '%v'", githubAuthStorageVolumeName) + } + + labels := map[*docker_label_key.DockerLabelKey]*docker_label_value.DockerLabelValue{ + docker_label_key.VolumeTypeDockerLabelKey: label_value_consts.GitHubAuthStorageVolumeTypeDockerLabelValue, + } + + objectAttributes, err := newDockerObjectAttributesImpl(name, labels) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred while creating the ObjectAttributesImpl with the name '%s' and labels '%+v'", name, labels) + } + return objectAttributes, nil +} + func (provider *dockerObjectAttributesProviderImpl) ForReverseProxy(engineGuid engine.EngineGUID) (DockerObjectAttributes, error) { nameStr := strings.Join( diff --git a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/engine_functions/create_engine.go b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/engine_functions/create_engine.go index ce6008782b..7ae80fe211 100644 --- a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/engine_functions/create_engine.go +++ b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/engine_functions/create_engine.go @@ -41,9 +41,11 @@ func CreateEngine( imageVersionTag string, grpcPortNum uint16, envVars map[string]string, + _ bool, //It's not required to add extra configuration in K8S for enabling the debug server + githubAuthToken string, kubernetesManager *kubernetes_manager.KubernetesManager, objAttrsProvider object_attributes_provider.KubernetesObjectAttributesProvider, - _ bool, //It's not required to add extra configuration in K8S for enabling the debug server + ) ( *engine.Engine, error, diff --git a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend.go index b9bd72017f..d87cd0b358 100644 --- a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend.go @@ -132,6 +132,7 @@ func (backend *KubernetesKurtosisBackend) CreateEngine( grpcPortNum uint16, envVars map[string]string, shouldStartInDebugMode bool, + githubAuthToken string, ) ( *engine.Engine, error, @@ -142,9 +143,10 @@ func (backend *KubernetesKurtosisBackend) CreateEngine( imageVersionTag, grpcPortNum, envVars, + shouldStartInDebugMode, + githubAuthToken, backend.kubernetesManager, backend.objAttrsProvider, - shouldStartInDebugMode, ) if err != nil { return nil, stacktrace.Propagate( diff --git a/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go index dcdbbf3b74..5a695e7537 100644 --- a/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go @@ -53,6 +53,7 @@ func (backend *MetricsReportingKurtosisBackend) CreateEngine( grpcPortNum uint16, envVars map[string]string, shouldStartInDebugMode bool, + githubAuthToken string, ) (*engine.Engine, error) { result, err := backend.underlying.CreateEngine( ctx, @@ -61,6 +62,7 @@ func (backend *MetricsReportingKurtosisBackend) CreateEngine( grpcPortNum, envVars, shouldStartInDebugMode, + githubAuthToken, ) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred creating the engine using image '%v' with tag '%v' and debug mode '%v'", imageOrgAndRepo, imageVersionTag, shouldStartInDebugMode) diff --git a/container-engine-lib/lib/backend_interface/kurtosis_backend.go b/container-engine-lib/lib/backend_interface/kurtosis_backend.go index 0e23bf4f8e..be9a65024f 100644 --- a/container-engine-lib/lib/backend_interface/kurtosis_backend.go +++ b/container-engine-lib/lib/backend_interface/kurtosis_backend.go @@ -47,6 +47,7 @@ type KurtosisBackend interface { grpcPortNum uint16, envVars map[string]string, shouldStartInDebugMode bool, + githubAuthToken string, ) ( *engine.Engine, error, diff --git a/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go b/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go index 554300cdae..62e2d0eb5f 100644 --- a/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.40.1. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package backend_interface @@ -52,10 +52,6 @@ func (_m *MockKurtosisBackend) EXPECT() *MockKurtosisBackend_Expecter { func (_m *MockKurtosisBackend) BuildImage(ctx context.Context, imageName string, imageBuildSpec *image_build_spec.ImageBuildSpec) (string, error) { ret := _m.Called(ctx, imageName, imageBuildSpec) - if len(ret) == 0 { - panic("no return value specified for BuildImage") - } - var r0 string var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, *image_build_spec.ImageBuildSpec) (string, error)); ok { @@ -110,10 +106,6 @@ func (_c *MockKurtosisBackend_BuildImage_Call) RunAndReturn(run func(context.Con func (_m *MockKurtosisBackend) CopyFilesFromUserService(ctx context.Context, enclaveUuid enclave.EnclaveUUID, serviceUuid service.ServiceUUID, srcPathOnService string, output io.Writer) error { ret := _m.Called(ctx, enclaveUuid, serviceUuid, srcPathOnService, output) - if len(ret) == 0 { - panic("no return value specified for CopyFilesFromUserService") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID, service.ServiceUUID, string, io.Writer) error); ok { r0 = rf(ctx, enclaveUuid, serviceUuid, srcPathOnService, output) @@ -164,10 +156,6 @@ func (_m *MockKurtosisBackend) CreateAPIContainer(ctx context.Context, image str panic("no return value specified for CreateAPIContainer") } - if len(ret) == 0 { - panic("no return value specified for CreateAPIContainer") - } - var r0 *api_container.APIContainer var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string, bool) (*api_container.APIContainer, error)); ok { @@ -229,10 +217,6 @@ func (_c *MockKurtosisBackend_CreateAPIContainer_Call) RunAndReturn(run func(con func (_m *MockKurtosisBackend) CreateEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID, enclaveName string) (*enclave.Enclave, error) { ret := _m.Called(ctx, enclaveUuid, enclaveName) - if len(ret) == 0 { - panic("no return value specified for CreateEnclave") - } - var r0 *enclave.Enclave var r1 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID, string) (*enclave.Enclave, error)); ok { @@ -285,29 +269,25 @@ func (_c *MockKurtosisBackend_CreateEnclave_Call) RunAndReturn(run func(context. return _c } -// CreateEngine provides a mock function with given fields: ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode -func (_m *MockKurtosisBackend) CreateEngine(ctx context.Context, imageOrgAndRepo string, imageVersionTag string, grpcPortNum uint16, envVars map[string]string, shouldStartInDebugMode bool) (*engine.Engine, error) { - ret := _m.Called(ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode) - - if len(ret) == 0 { - panic("no return value specified for CreateEngine") - } +// CreateEngine provides a mock function with given fields: ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode, githubAuthToken +func (_m *MockKurtosisBackend) CreateEngine(ctx context.Context, imageOrgAndRepo string, imageVersionTag string, grpcPortNum uint16, envVars map[string]string, shouldStartInDebugMode bool, githubAuthToken string) (*engine.Engine, error) { + ret := _m.Called(ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode, githubAuthToken) var r0 *engine.Engine var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, uint16, map[string]string, bool) (*engine.Engine, error)); ok { - return rf(ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode) + if rf, ok := ret.Get(0).(func(context.Context, string, string, uint16, map[string]string, bool, string) (*engine.Engine, error)); ok { + return rf(ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode, githubAuthToken) } - if rf, ok := ret.Get(0).(func(context.Context, string, string, uint16, map[string]string, bool) *engine.Engine); ok { - r0 = rf(ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode) + if rf, ok := ret.Get(0).(func(context.Context, string, string, uint16, map[string]string, bool, string) *engine.Engine); ok { + r0 = rf(ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode, githubAuthToken) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*engine.Engine) } } - if rf, ok := ret.Get(1).(func(context.Context, string, string, uint16, map[string]string, bool) error); ok { - r1 = rf(ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode) + if rf, ok := ret.Get(1).(func(context.Context, string, string, uint16, map[string]string, bool, string) error); ok { + r1 = rf(ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode, githubAuthToken) } else { r1 = ret.Error(1) } @@ -327,13 +307,14 @@ type MockKurtosisBackend_CreateEngine_Call struct { // - grpcPortNum uint16 // - envVars map[string]string // - shouldStartInDebugMode bool -func (_e *MockKurtosisBackend_Expecter) CreateEngine(ctx interface{}, imageOrgAndRepo interface{}, imageVersionTag interface{}, grpcPortNum interface{}, envVars interface{}, shouldStartInDebugMode interface{}) *MockKurtosisBackend_CreateEngine_Call { - return &MockKurtosisBackend_CreateEngine_Call{Call: _e.mock.On("CreateEngine", ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode)} +// - githubAuthToken string +func (_e *MockKurtosisBackend_Expecter) CreateEngine(ctx interface{}, imageOrgAndRepo interface{}, imageVersionTag interface{}, grpcPortNum interface{}, envVars interface{}, shouldStartInDebugMode interface{}, githubAuthToken interface{}) *MockKurtosisBackend_CreateEngine_Call { + return &MockKurtosisBackend_CreateEngine_Call{Call: _e.mock.On("CreateEngine", ctx, imageOrgAndRepo, imageVersionTag, grpcPortNum, envVars, shouldStartInDebugMode, githubAuthToken)} } -func (_c *MockKurtosisBackend_CreateEngine_Call) Run(run func(ctx context.Context, imageOrgAndRepo string, imageVersionTag string, grpcPortNum uint16, envVars map[string]string, shouldStartInDebugMode bool)) *MockKurtosisBackend_CreateEngine_Call { +func (_c *MockKurtosisBackend_CreateEngine_Call) Run(run func(ctx context.Context, imageOrgAndRepo string, imageVersionTag string, grpcPortNum uint16, envVars map[string]string, shouldStartInDebugMode bool, githubAuthToken string)) *MockKurtosisBackend_CreateEngine_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(uint16), args[4].(map[string]string), args[5].(bool)) + run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(uint16), args[4].(map[string]string), args[5].(bool), args[6].(string)) }) return _c } @@ -343,7 +324,7 @@ func (_c *MockKurtosisBackend_CreateEngine_Call) Return(_a0 *engine.Engine, _a1 return _c } -func (_c *MockKurtosisBackend_CreateEngine_Call) RunAndReturn(run func(context.Context, string, string, uint16, map[string]string, bool) (*engine.Engine, error)) *MockKurtosisBackend_CreateEngine_Call { +func (_c *MockKurtosisBackend_CreateEngine_Call) RunAndReturn(run func(context.Context, string, string, uint16, map[string]string, bool, string) (*engine.Engine, error)) *MockKurtosisBackend_CreateEngine_Call { _c.Call.Return(run) return _c } @@ -352,10 +333,6 @@ func (_c *MockKurtosisBackend_CreateEngine_Call) RunAndReturn(run func(context.C func (_m *MockKurtosisBackend) CreateLogsAggregator(ctx context.Context) (*logs_aggregator.LogsAggregator, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for CreateLogsAggregator") - } - var r0 *logs_aggregator.LogsAggregator var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*logs_aggregator.LogsAggregator, error)); ok { @@ -410,10 +387,6 @@ func (_c *MockKurtosisBackend_CreateLogsAggregator_Call) RunAndReturn(run func(c func (_m *MockKurtosisBackend) CreateLogsCollectorForEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID, logsCollectorHttpPortNumber uint16, logsCollectorTcpPortNumber uint16) (*logs_collector.LogsCollector, error) { ret := _m.Called(ctx, enclaveUuid, logsCollectorHttpPortNumber, logsCollectorTcpPortNumber) - if len(ret) == 0 { - panic("no return value specified for CreateLogsCollectorForEnclave") - } - var r0 *logs_collector.LogsCollector var r1 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID, uint16, uint16) (*logs_collector.LogsCollector, error)); ok { @@ -471,10 +444,6 @@ func (_c *MockKurtosisBackend_CreateLogsCollectorForEnclave_Call) RunAndReturn(r func (_m *MockKurtosisBackend) CreateReverseProxy(ctx context.Context, engineGuid engine.EngineGUID) (*reverse_proxy.ReverseProxy, error) { ret := _m.Called(ctx, engineGuid) - if len(ret) == 0 { - panic("no return value specified for CreateReverseProxy") - } - var r0 *reverse_proxy.ReverseProxy var r1 error if rf, ok := ret.Get(0).(func(context.Context, engine.EngineGUID) (*reverse_proxy.ReverseProxy, error)); ok { @@ -530,10 +499,6 @@ func (_c *MockKurtosisBackend_CreateReverseProxy_Call) RunAndReturn(run func(con func (_m *MockKurtosisBackend) DestroyAPIContainers(ctx context.Context, filters *api_container.APIContainerFilters) (map[enclave.EnclaveUUID]bool, map[enclave.EnclaveUUID]error, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for DestroyAPIContainers") - } - var r0 map[enclave.EnclaveUUID]bool var r1 map[enclave.EnclaveUUID]error var r2 error @@ -598,10 +563,6 @@ func (_c *MockKurtosisBackend_DestroyAPIContainers_Call) RunAndReturn(run func(c func (_m *MockKurtosisBackend) DestroyEnclaves(ctx context.Context, filters *enclave.EnclaveFilters) (map[enclave.EnclaveUUID]bool, map[enclave.EnclaveUUID]error, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for DestroyEnclaves") - } - var r0 map[enclave.EnclaveUUID]bool var r1 map[enclave.EnclaveUUID]error var r2 error @@ -666,10 +627,6 @@ func (_c *MockKurtosisBackend_DestroyEnclaves_Call) RunAndReturn(run func(contex func (_m *MockKurtosisBackend) DestroyEngines(ctx context.Context, filters *engine.EngineFilters) (map[engine.EngineGUID]bool, map[engine.EngineGUID]error, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for DestroyEngines") - } - var r0 map[engine.EngineGUID]bool var r1 map[engine.EngineGUID]error var r2 error @@ -734,10 +691,6 @@ func (_c *MockKurtosisBackend_DestroyEngines_Call) RunAndReturn(run func(context func (_m *MockKurtosisBackend) DestroyLogsAggregator(ctx context.Context) error { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for DestroyLogsAggregator") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(ctx) @@ -780,10 +733,6 @@ func (_c *MockKurtosisBackend_DestroyLogsAggregator_Call) RunAndReturn(run func( func (_m *MockKurtosisBackend) DestroyLogsCollectorForEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID) error { ret := _m.Called(ctx, enclaveUuid) - if len(ret) == 0 { - panic("no return value specified for DestroyLogsCollectorForEnclave") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID) error); ok { r0 = rf(ctx, enclaveUuid) @@ -827,10 +776,6 @@ func (_c *MockKurtosisBackend_DestroyLogsCollectorForEnclave_Call) RunAndReturn( func (_m *MockKurtosisBackend) DestroyReverseProxy(ctx context.Context) error { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for DestroyReverseProxy") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(ctx) @@ -873,10 +818,6 @@ func (_c *MockKurtosisBackend_DestroyReverseProxy_Call) RunAndReturn(run func(co func (_m *MockKurtosisBackend) DestroyUserServices(ctx context.Context, enclaveUuid enclave.EnclaveUUID, filters *service.ServiceFilters) (map[service.ServiceUUID]bool, map[service.ServiceUUID]error, error) { ret := _m.Called(ctx, enclaveUuid, filters) - if len(ret) == 0 { - panic("no return value specified for DestroyUserServices") - } - var r0 map[service.ServiceUUID]bool var r1 map[service.ServiceUUID]error var r2 error @@ -942,10 +883,6 @@ func (_c *MockKurtosisBackend_DestroyUserServices_Call) RunAndReturn(run func(co func (_m *MockKurtosisBackend) DumpEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID, outputDirpath string) error { ret := _m.Called(ctx, enclaveUuid, outputDirpath) - if len(ret) == 0 { - panic("no return value specified for DumpEnclave") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID, string) error); ok { r0 = rf(ctx, enclaveUuid, outputDirpath) @@ -990,10 +927,6 @@ func (_c *MockKurtosisBackend_DumpEnclave_Call) RunAndReturn(run func(context.Co func (_m *MockKurtosisBackend) DumpKurtosis(ctx context.Context, outputDirpath string) error { ret := _m.Called(ctx, outputDirpath) - if len(ret) == 0 { - panic("no return value specified for DumpKurtosis") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { r0 = rf(ctx, outputDirpath) @@ -1037,10 +970,6 @@ func (_c *MockKurtosisBackend_DumpKurtosis_Call) RunAndReturn(run func(context.C func (_m *MockKurtosisBackend) FetchImage(ctx context.Context, image string, registrySpec *image_registry_spec.ImageRegistrySpec, downloadMode image_download_mode.ImageDownloadMode) (bool, string, error) { ret := _m.Called(ctx, image, registrySpec, downloadMode) - if len(ret) == 0 { - panic("no return value specified for FetchImage") - } - var r0 bool var r1 string var r2 error @@ -1103,10 +1032,6 @@ func (_c *MockKurtosisBackend_FetchImage_Call) RunAndReturn(run func(context.Con func (_m *MockKurtosisBackend) GetAPIContainers(ctx context.Context, filters *api_container.APIContainerFilters) (map[enclave.EnclaveUUID]*api_container.APIContainer, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for GetAPIContainers") - } - var r0 map[enclave.EnclaveUUID]*api_container.APIContainer var r1 error if rf, ok := ret.Get(0).(func(context.Context, *api_container.APIContainerFilters) (map[enclave.EnclaveUUID]*api_container.APIContainer, error)); ok { @@ -1162,10 +1087,6 @@ func (_c *MockKurtosisBackend_GetAPIContainers_Call) RunAndReturn(run func(conte func (_m *MockKurtosisBackend) GetAvailableCPUAndMemory(ctx context.Context) (compute_resources.MemoryInMegaBytes, compute_resources.CpuMilliCores, bool, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for GetAvailableCPUAndMemory") - } - var r0 compute_resources.MemoryInMegaBytes var r1 compute_resources.CpuMilliCores var r2 bool @@ -1232,10 +1153,6 @@ func (_c *MockKurtosisBackend_GetAvailableCPUAndMemory_Call) RunAndReturn(run fu func (_m *MockKurtosisBackend) GetEnclaves(ctx context.Context, filters *enclave.EnclaveFilters) (map[enclave.EnclaveUUID]*enclave.Enclave, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for GetEnclaves") - } - var r0 map[enclave.EnclaveUUID]*enclave.Enclave var r1 error if rf, ok := ret.Get(0).(func(context.Context, *enclave.EnclaveFilters) (map[enclave.EnclaveUUID]*enclave.Enclave, error)); ok { @@ -1291,10 +1208,6 @@ func (_c *MockKurtosisBackend_GetEnclaves_Call) RunAndReturn(run func(context.Co func (_m *MockKurtosisBackend) GetEngineLogs(ctx context.Context, outputDirpath string) error { ret := _m.Called(ctx, outputDirpath) - if len(ret) == 0 { - panic("no return value specified for GetEngineLogs") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { r0 = rf(ctx, outputDirpath) @@ -1338,10 +1251,6 @@ func (_c *MockKurtosisBackend_GetEngineLogs_Call) RunAndReturn(run func(context. func (_m *MockKurtosisBackend) GetEngines(ctx context.Context, filters *engine.EngineFilters) (map[engine.EngineGUID]*engine.Engine, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for GetEngines") - } - var r0 map[engine.EngineGUID]*engine.Engine var r1 error if rf, ok := ret.Get(0).(func(context.Context, *engine.EngineFilters) (map[engine.EngineGUID]*engine.Engine, error)); ok { @@ -1397,10 +1306,6 @@ func (_c *MockKurtosisBackend_GetEngines_Call) RunAndReturn(run func(context.Con func (_m *MockKurtosisBackend) GetLogsAggregator(ctx context.Context) (*logs_aggregator.LogsAggregator, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for GetLogsAggregator") - } - var r0 *logs_aggregator.LogsAggregator var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*logs_aggregator.LogsAggregator, error)); ok { @@ -1455,10 +1360,6 @@ func (_c *MockKurtosisBackend_GetLogsAggregator_Call) RunAndReturn(run func(cont func (_m *MockKurtosisBackend) GetLogsCollectorForEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID) (*logs_collector.LogsCollector, error) { ret := _m.Called(ctx, enclaveUuid) - if len(ret) == 0 { - panic("no return value specified for GetLogsCollectorForEnclave") - } - var r0 *logs_collector.LogsCollector var r1 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID) (*logs_collector.LogsCollector, error)); ok { @@ -1514,10 +1415,6 @@ func (_c *MockKurtosisBackend_GetLogsCollectorForEnclave_Call) RunAndReturn(run func (_m *MockKurtosisBackend) GetReverseProxy(ctx context.Context) (*reverse_proxy.ReverseProxy, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for GetReverseProxy") - } - var r0 *reverse_proxy.ReverseProxy var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*reverse_proxy.ReverseProxy, error)); ok { @@ -1572,10 +1469,6 @@ func (_c *MockKurtosisBackend_GetReverseProxy_Call) RunAndReturn(run func(contex func (_m *MockKurtosisBackend) GetShellOnUserService(ctx context.Context, enclaveUuid enclave.EnclaveUUID, serviceUuid service.ServiceUUID) error { ret := _m.Called(ctx, enclaveUuid, serviceUuid) - if len(ret) == 0 { - panic("no return value specified for GetShellOnUserService") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID, service.ServiceUUID) error); ok { r0 = rf(ctx, enclaveUuid, serviceUuid) @@ -1620,10 +1513,6 @@ func (_c *MockKurtosisBackend_GetShellOnUserService_Call) RunAndReturn(run func( func (_m *MockKurtosisBackend) GetUserServiceLogs(ctx context.Context, enclaveUuid enclave.EnclaveUUID, filters *service.ServiceFilters, shouldFollowLogs bool) (map[service.ServiceUUID]io.ReadCloser, map[service.ServiceUUID]error, error) { ret := _m.Called(ctx, enclaveUuid, filters, shouldFollowLogs) - if len(ret) == 0 { - panic("no return value specified for GetUserServiceLogs") - } - var r0 map[service.ServiceUUID]io.ReadCloser var r1 map[service.ServiceUUID]error var r2 error @@ -1690,10 +1579,6 @@ func (_c *MockKurtosisBackend_GetUserServiceLogs_Call) RunAndReturn(run func(con func (_m *MockKurtosisBackend) GetUserServices(ctx context.Context, enclaveUuid enclave.EnclaveUUID, filters *service.ServiceFilters) (map[service.ServiceUUID]*service.Service, error) { ret := _m.Called(ctx, enclaveUuid, filters) - if len(ret) == 0 { - panic("no return value specified for GetUserServices") - } - var r0 map[service.ServiceUUID]*service.Service var r1 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID, *service.ServiceFilters) (map[service.ServiceUUID]*service.Service, error)); ok { @@ -1750,10 +1635,6 @@ func (_c *MockKurtosisBackend_GetUserServices_Call) RunAndReturn(run func(contex func (_m *MockKurtosisBackend) PruneUnusedImages(ctx context.Context) ([]string, error) { ret := _m.Called(ctx) - if len(ret) == 0 { - panic("no return value specified for PruneUnusedImages") - } - var r0 []string var r1 error if rf, ok := ret.Get(0).(func(context.Context) ([]string, error)); ok { @@ -1808,10 +1689,6 @@ func (_c *MockKurtosisBackend_PruneUnusedImages_Call) RunAndReturn(run func(cont func (_m *MockKurtosisBackend) RegisterUserServices(ctx context.Context, enclaveUuid enclave.EnclaveUUID, services map[service.ServiceName]bool) (map[service.ServiceName]*service.ServiceRegistration, map[service.ServiceName]error, error) { ret := _m.Called(ctx, enclaveUuid, services) - if len(ret) == 0 { - panic("no return value specified for RegisterUserServices") - } - var r0 map[service.ServiceName]*service.ServiceRegistration var r1 map[service.ServiceName]error var r2 error @@ -1877,10 +1754,6 @@ func (_c *MockKurtosisBackend_RegisterUserServices_Call) RunAndReturn(run func(c func (_m *MockKurtosisBackend) RemoveRegisteredUserServiceProcesses(ctx context.Context, enclaveUuid enclave.EnclaveUUID, services map[service.ServiceUUID]bool) (map[service.ServiceUUID]bool, map[service.ServiceUUID]error, error) { ret := _m.Called(ctx, enclaveUuid, services) - if len(ret) == 0 { - panic("no return value specified for RemoveRegisteredUserServiceProcesses") - } - var r0 map[service.ServiceUUID]bool var r1 map[service.ServiceUUID]error var r2 error @@ -1946,10 +1819,6 @@ func (_c *MockKurtosisBackend_RemoveRegisteredUserServiceProcesses_Call) RunAndR func (_m *MockKurtosisBackend) RunUserServiceExecCommandWithStreamedOutput(ctx context.Context, enclaveUuid enclave.EnclaveUUID, serviceUuid service.ServiceUUID, cmd []string) (chan string, chan *exec_result.ExecResult, error) { ret := _m.Called(ctx, enclaveUuid, serviceUuid, cmd) - if len(ret) == 0 { - panic("no return value specified for RunUserServiceExecCommandWithStreamedOutput") - } - var r0 chan string var r1 chan *exec_result.ExecResult var r2 error @@ -2016,10 +1885,6 @@ func (_c *MockKurtosisBackend_RunUserServiceExecCommandWithStreamedOutput_Call) func (_m *MockKurtosisBackend) RunUserServiceExecCommands(ctx context.Context, enclaveUuid enclave.EnclaveUUID, userServiceCommands map[service.ServiceUUID][]string) (map[service.ServiceUUID]*exec_result.ExecResult, map[service.ServiceUUID]error, error) { ret := _m.Called(ctx, enclaveUuid, userServiceCommands) - if len(ret) == 0 { - panic("no return value specified for RunUserServiceExecCommands") - } - var r0 map[service.ServiceUUID]*exec_result.ExecResult var r1 map[service.ServiceUUID]error var r2 error @@ -2085,10 +1950,6 @@ func (_c *MockKurtosisBackend_RunUserServiceExecCommands_Call) RunAndReturn(run func (_m *MockKurtosisBackend) StartRegisteredUserServices(ctx context.Context, enclaveUuid enclave.EnclaveUUID, services map[service.ServiceUUID]*service.ServiceConfig) (map[service.ServiceUUID]*service.Service, map[service.ServiceUUID]error, error) { ret := _m.Called(ctx, enclaveUuid, services) - if len(ret) == 0 { - panic("no return value specified for StartRegisteredUserServices") - } - var r0 map[service.ServiceUUID]*service.Service var r1 map[service.ServiceUUID]error var r2 error @@ -2154,10 +2015,6 @@ func (_c *MockKurtosisBackend_StartRegisteredUserServices_Call) RunAndReturn(run func (_m *MockKurtosisBackend) StopAPIContainers(ctx context.Context, filters *api_container.APIContainerFilters) (map[enclave.EnclaveUUID]bool, map[enclave.EnclaveUUID]error, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for StopAPIContainers") - } - var r0 map[enclave.EnclaveUUID]bool var r1 map[enclave.EnclaveUUID]error var r2 error @@ -2222,10 +2079,6 @@ func (_c *MockKurtosisBackend_StopAPIContainers_Call) RunAndReturn(run func(cont func (_m *MockKurtosisBackend) StopEnclaves(ctx context.Context, filters *enclave.EnclaveFilters) (map[enclave.EnclaveUUID]bool, map[enclave.EnclaveUUID]error, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for StopEnclaves") - } - var r0 map[enclave.EnclaveUUID]bool var r1 map[enclave.EnclaveUUID]error var r2 error @@ -2290,10 +2143,6 @@ func (_c *MockKurtosisBackend_StopEnclaves_Call) RunAndReturn(run func(context.C func (_m *MockKurtosisBackend) StopEngines(ctx context.Context, filters *engine.EngineFilters) (map[engine.EngineGUID]bool, map[engine.EngineGUID]error, error) { ret := _m.Called(ctx, filters) - if len(ret) == 0 { - panic("no return value specified for StopEngines") - } - var r0 map[engine.EngineGUID]bool var r1 map[engine.EngineGUID]error var r2 error @@ -2358,10 +2207,6 @@ func (_c *MockKurtosisBackend_StopEngines_Call) RunAndReturn(run func(context.Co func (_m *MockKurtosisBackend) StopUserServices(ctx context.Context, enclaveUuid enclave.EnclaveUUID, filters *service.ServiceFilters) (map[service.ServiceUUID]bool, map[service.ServiceUUID]error, error) { ret := _m.Called(ctx, enclaveUuid, filters) - if len(ret) == 0 { - panic("no return value specified for StopUserServices") - } - var r0 map[service.ServiceUUID]bool var r1 map[service.ServiceUUID]error var r2 error @@ -2427,10 +2272,6 @@ func (_c *MockKurtosisBackend_StopUserServices_Call) RunAndReturn(run func(conte func (_m *MockKurtosisBackend) UnregisterUserServices(ctx context.Context, enclaveUuid enclave.EnclaveUUID, services map[service.ServiceUUID]bool) (map[service.ServiceUUID]bool, map[service.ServiceUUID]error, error) { ret := _m.Called(ctx, enclaveUuid, services) - if len(ret) == 0 { - panic("no return value specified for UnregisterUserServices") - } - var r0 map[service.ServiceUUID]bool var r1 map[service.ServiceUUID]error var r2 error @@ -2496,10 +2337,6 @@ func (_c *MockKurtosisBackend_UnregisterUserServices_Call) RunAndReturn(run func func (_m *MockKurtosisBackend) UpdateEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID, newName string, creationTime *time.Time) error { ret := _m.Called(ctx, enclaveUuid, newName, creationTime) - if len(ret) == 0 { - panic("no return value specified for UpdateEnclave") - } - var r0 error if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID, string, *time.Time) error); ok { r0 = rf(ctx, enclaveUuid, newName, creationTime) @@ -2541,12 +2378,13 @@ func (_c *MockKurtosisBackend_UpdateEnclave_Call) RunAndReturn(run func(context. return _c } -// NewMockKurtosisBackend creates a new instance of MockKurtosisBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockKurtosisBackend(t interface { +type mockConstructorTestingTNewMockKurtosisBackend interface { mock.TestingT Cleanup(func()) -}) *MockKurtosisBackend { +} + +// NewMockKurtosisBackend creates a new instance of MockKurtosisBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockKurtosisBackend(t mockConstructorTestingTNewMockKurtosisBackend) *MockKurtosisBackend { mock := &MockKurtosisBackend{} mock.Mock.Test(t) diff --git a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider.go b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider.go index 1580f8c93c..a3cf9e0cfc 100644 --- a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider.go +++ b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider.go @@ -4,15 +4,19 @@ import ( "errors" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/kurtosis-tech/kurtosis/api/golang/core/lib/shared_utils" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/database_accessors/enclave_db" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/user_support_constants" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_constants" "github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors" "github.com/kurtosis-tech/kurtosis/core/server/commons/yaml_parser" + "github.com/kurtosis-tech/stacktrace" "github.com/mholt/archiver" "github.com/sirupsen/logrus" "io" + "io/fs" "os" "path" "strings" @@ -48,12 +52,15 @@ type GitPackageContentProvider struct { repositoriesTmpDir string repositoriesDir string packageReplaceOptionsRepository *packageReplaceOptionsRepository + + githubAuthTokenFile string } -func NewGitPackageContentProvider(repositoriesDir string, tmpDir string, enclaveDb *enclave_db.EnclaveDB) *GitPackageContentProvider { +func NewGitPackageContentProvider(repositoriesDir, tmpDir, githubAuthTokenFile string, enclaveDb *enclave_db.EnclaveDB) *GitPackageContentProvider { return &GitPackageContentProvider{ repositoriesDir: repositoriesDir, repositoriesTmpDir: tmpDir, + githubAuthTokenFile: githubAuthTokenFile, packageReplaceOptionsRepository: newPackageReplaceOptionsRepository(enclaveDb), } } @@ -313,12 +320,24 @@ func (provider *GitPackageContentProvider) atomicClone(parsedURL *shared_utils.P depth = depthAssumingBranchTagsCommitsAreSpecified } + var githubAuth *http.BasicAuth + githubAuthToken, err := provider.getGitHubAuthToken() + if err != nil { + return startosis_errors.WrapWithInterpretationError(err, "An error occurred retrieving GitHub auth token.") + } + if githubAuthToken != "" { + githubAuth = &http.BasicAuth{ + Username: "token", + Password: githubAuthToken, + } + } + //TODO evaluate to use the GitHub client GetContents call instead, because we are cloning the entire repository's workspace with this approach //TODO and the startosis package could be just a small sub-folder inside a giant mono-repository //TODO and even now, in the upload_files instruction, we are allowing to upload files or a folder for any repository, but we are cloning the entire repository for this repo, err := git.PlainClone(gitClonePath, isNotBareClone, &git.CloneOptions{ URL: parsedURL.GetGitURL(), - Auth: nil, + Auth: githubAuth, RemoteName: "", ReferenceName: "", SingleBranch: false, @@ -329,13 +348,20 @@ func (provider *GitPackageContentProvider) atomicClone(parsedURL *shared_utils.P Tags: 0, InsecureSkipTLS: false, CABundle: nil, + Mirror: false, + ShallowSubmodules: false, + ProxyOptions: transport.ProxyOptions{ + URL: "", + Username: "", + Password: "", + }, + Shared: false, }) if err != nil { - // TODO remove public repository from error after we support private repositories // We silent the underlying error here as it can be confusing to the user. For example, when there's a typo in // the repo name, pointing to a non existing repo, the underlying error is: "authentication required" logrus.Errorf("Error cloning git repository: '%s' to '%s'. Error was: \n%s", parsedURL.GetGitURL(), gitClonePath, err.Error()) - return startosis_errors.NewInterpretationError("Error in cloning git repository '%s' to '%s'. Make sure that '%v' exists and is a public repository.", parsedURL.GetGitURL(), gitClonePath, parsedURL.GetGitURL()) + return startosis_errors.NewInterpretationError("Error in cloning git repository '%s' to '%s'. Make sure that '%v' exists or if it's a private repository, that you are logged into GitHub via `kurtosis github login`.", parsedURL.GetGitURL(), gitClonePath, parsedURL.GetGitURL()) } if parsedURL.GetTagBranchOrCommit() != emptyTagBranchOrCommit { @@ -345,11 +371,12 @@ func (provider *GitPackageContentProvider) atomicClone(parsedURL *shared_utils.P } checkoutOptions := &git.CheckoutOptions{ - Hash: plumbing.Hash{}, - Branch: "", - Create: false, - Force: false, - Keep: false, + Hash: plumbing.Hash{}, + Branch: "", + Create: false, + Force: false, + Keep: false, + SparseCheckoutDirectories: []string{}, } if found { // if we have a tag or branch we set it @@ -398,6 +425,18 @@ func (provider *GitPackageContentProvider) atomicClone(parsedURL *shared_utils.P return nil } +// Returns empty string if no token found in [githubAuthTokenFile] or [githubAuthTokenFile] doesn't exist +func (provider *GitPackageContentProvider) getGitHubAuthToken() (string, error) { + tokenBytes, err := os.ReadFile(provider.githubAuthTokenFile) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return "", nil + } + return "", stacktrace.Propagate(err, "An error occurred reading contents at '%v' to retrieve GitHub auth token.", provider.githubAuthTokenFile) + } + return string(tokenBytes), nil +} + // methods checks whether the root of the package is same as repository root // or it is a sub-folder under it func getPathToPackageRoot(parsedPackagePath *shared_utils.ParsedGitURL) string { diff --git a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider_test.go b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider_test.go index 33d221124a..9d6e367497 100644 --- a/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider_test.go +++ b/core/server/api_container/server/startosis_engine/startosis_packages/git_package_content_provider/git_package_content_provider_test.go @@ -18,6 +18,8 @@ import ( const ( packagesDirRelPath = "startosis-packages" repositoriesTmpDirRelPath = "tmp-repositories" + githubAuthDirRelPath = "github-auth" + githubAuthTokenFilename = "token.txt" genericRepositoriesDirRelPath = "generic-repositories" packageDescriptionForTest = "package description test" localAbsoluteLocatorNotAllowedMsg = "is referencing a file within the same package using absolute import syntax" @@ -32,8 +34,13 @@ func TestGitPackageProvider_SucceedsForValidPackage(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) sampleStartosisModule := "github.com/kurtosis-tech/sample-startosis-load/sample.star" contents, err := provider.GetModuleContents(sampleStartosisModule) @@ -48,8 +55,13 @@ func TestGitPackageProvider_SucceedsForValidPackageWithExplicitMasterSet(t *test packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) sampleStartosisModule := "github.com/kurtosis-tech/sample-startosis-load/sample.star@main" contents, err := provider.GetModuleContents(sampleStartosisModule) @@ -64,8 +76,13 @@ func TestGitPackageProvider_SucceedsForValidPackageWithBranch(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) sampleStartosisModule := "github.com/kurtosis-tech/sample-startosis-load/sample.star@test-branch" contents, err := provider.GetModuleContents(sampleStartosisModule) @@ -80,8 +97,13 @@ func TestGitPackageProvider_FailsForInvalidBranch(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) sampleStartosisModule := "github.com/kurtosis-tech/sample-startosis-load/sample.star@non-existent-branch" _, err = provider.GetModuleContents(sampleStartosisModule) @@ -95,8 +117,13 @@ func TestGitPackageProvider_SucceedsForValidPackageWithTag(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) sampleStartosisModule := "github.com/kurtosis-tech/sample-startosis-load/sample.star@0.1.1" contents, err := provider.GetModuleContents(sampleStartosisModule) @@ -111,8 +138,13 @@ func TestGitPackageProvider_SucceedsForValidPackageWithCommit(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) sampleStartosisModule := "github.com/kurtosis-tech/sample-startosis-load/sample.star@ec9062828e1a687a5db7dfa750f754f88119e4c0" contents, err := provider.GetModuleContents(sampleStartosisModule) @@ -127,8 +159,13 @@ func TestGitPackageProvider_SucceedsForValidPackageWithCommitOnABranch(t *testin packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) sampleStartosisModule := "github.com/kurtosis-tech/sample-startosis-load/sample.star@df88baf51caffbe7e8f66c0e54715f680f4482b2" contents, err := provider.GetModuleContents(sampleStartosisModule) @@ -143,8 +180,13 @@ func TestGitPackageProvider_SucceedsForNonStarlarkFile(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) // TODO replace this with something local or static sampleStarlarkPackage := "github.com/kurtosis-tech/prometheus-package/static-files/prometheus.yml.tmpl" @@ -160,8 +202,13 @@ func TestGitPackageProvider_FailsForNonExistentPackage(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(oackageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(oackageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) nonExistentModulePath := "github.com/kurtosis-tech/non-existent-startosis-load/sample.star" _, err = provider.GetModuleContents(nonExistentModulePath) @@ -175,8 +222,13 @@ func TestGetAbsolutePathOnDisk_WorksForPureDirectories(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) packagePath := "github.com/kurtosis-tech/datastore-army-package/src/helpers.star" pathOnDisk, err := provider.getOnDiskAbsolutePath(packagePath, true) @@ -192,8 +244,13 @@ func TestGetAbsolutePathOnDisk_WorksForNonInMainBranchLocators(t *testing.T) { packageTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, nil) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), nil) absoluteFileLocator := "github.com/kurtosis-tech/sample-dependency-package@test-branch/main.star" pathOnDisk, err := provider.getOnDiskAbsolutePath(absoluteFileLocator, true) @@ -206,12 +263,17 @@ func TestGetAbsolutePathOnDisk_GenericRepositoryDir(t *testing.T) { repositoriesDir, err := os.MkdirTemp("", packagesDirRelPath) require.Nil(t, err) defer os.RemoveAll(repositoriesDir) - repositoriesTmpDir, err := os.MkdirTemp("", repositoriesTmpDirRelPath) require.Nil(t, err) defer os.RemoveAll(repositoriesTmpDir) - provider := NewGitPackageContentProvider(repositoriesDir, repositoriesTmpDir, nil) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) + + provider := NewGitPackageContentProvider(repositoriesDir, repositoriesTmpDir, githubAuthTokenFilePath.Name(), nil) repositoryPathURL := "github.com/kurtosis-tech/minimal-grpc-server/golang/scripts" pathOnDisk, err := provider.GetOnDiskAbsolutePath(repositoryPathURL) @@ -229,7 +291,13 @@ func TestGetAbsolutePathOnDisk_GenericRepositoryFile(t *testing.T) { require.Nil(t, err) defer os.RemoveAll(repositoriesTmpDir) - provider := NewGitPackageContentProvider(repositoriesDir, repositoriesTmpDir, nil) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) + + provider := NewGitPackageContentProvider(repositoriesDir, repositoriesTmpDir, githubAuthTokenFilePath.Name(), nil) repositoryPathURL := "github.com/kurtosis-tech/minimal-grpc-server/golang/scripts/build.sh" pathOnDisk, err := provider.GetOnDiskAbsolutePath(repositoryPathURL) @@ -239,7 +307,7 @@ func TestGetAbsolutePathOnDisk_GenericRepositoryFile(t *testing.T) { } func TestGetAbsoluteLocator_SucceedsForRelativeFile(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/kurtosis-tech/avalanche-package" parentModuleId := "github.com/kurtosis-tech/avalanche-package/src/builder.star" @@ -260,7 +328,7 @@ func TestGetAbsoluteLocator_SucceedsForRelativeFile(t *testing.T) { } func TestGetAbsoluteLocator_RegularReplaceSucceeds(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" @@ -277,7 +345,7 @@ func TestGetAbsoluteLocator_RegularReplaceSucceeds(t *testing.T) { } func TestGetAbsoluteLocator_RootPackageReplaceSucceeds(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" @@ -295,7 +363,7 @@ func TestGetAbsoluteLocator_RootPackageReplaceSucceeds(t *testing.T) { } func TestGetAbsoluteLocator_SubPackageReplaceSucceeds(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" @@ -313,7 +381,7 @@ func TestGetAbsoluteLocator_SubPackageReplaceSucceeds(t *testing.T) { } func TestGetAbsoluteLocator_ReplacePackageInternalModuleSucceeds(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" @@ -329,7 +397,7 @@ func TestGetAbsoluteLocator_ReplacePackageInternalModuleSucceeds(t *testing.T) { } func TestGetAbsoluteLocator_NoMainBranchReplaceSucceeds(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/kurtosis-tech/sample-startosis-load/sample-package" parentModuleId := "github.com/kurtosis-tech/sample-startosis-load/sample-package/main.star" @@ -345,7 +413,7 @@ func TestGetAbsoluteLocator_NoMainBranchReplaceSucceeds(t *testing.T) { } func TestGetAbsoluteLocator_ShouldBlockSamePackageAbsoluteLocator(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/main-package" locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/main-package/main.star" @@ -356,7 +424,7 @@ func TestGetAbsoluteLocator_ShouldBlockSamePackageAbsoluteLocator(t *testing.T) } func TestGetAbsoluteLocator_ShouldBlockSamePackageAbsoluteLocatorInSubfolder(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/main-package" locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/main-package/main.star" @@ -367,7 +435,7 @@ func TestGetAbsoluteLocator_ShouldBlockSamePackageAbsoluteLocatorInSubfolder(t * } func TestGetAbsoluteLocator_SameRepositorySubpackagesShouldNotBeBlocked(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/main-project/package1-in-subfolder" locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/main-project/package1-in-subfolder/main.star" @@ -378,7 +446,7 @@ func TestGetAbsoluteLocator_SameRepositorySubpackagesShouldNotBeBlocked(t *testi } func TestGetAbsoluteLocator_RelativeLocatorShouldNotBeBlocked(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/main-package" locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/main-package/main.star" @@ -389,7 +457,7 @@ func TestGetAbsoluteLocator_RelativeLocatorShouldNotBeBlocked(t *testing.T) { } func TestGetAbsoluteLocator_AbsoluteLocatorIsInRootPackageButSourceIsNotShouldNotBeBlocked(t *testing.T) { - provider := NewGitPackageContentProvider("", "", nil) + provider := NewGitPackageContentProvider("", "", "", nil) packageId := "github.com/main-package" locatorOfModuleInWhichThisBuiltInIsBeingCalled := "github.com/child-package/main.star" @@ -598,9 +666,15 @@ func TestCloneReplacedPackagesIfNeeded_Succeeds(t *testing.T) { require.Nil(t, err) defer os.RemoveAll(packageTmpDir) + githubAuthDir, err := os.MkdirTemp("", githubAuthDirRelPath) + require.Nil(t, err) + githubAuthTokenFilePath, err := os.CreateTemp(githubAuthDir, githubAuthTokenFilename) + require.Nil(t, err) + defer os.RemoveAll(githubAuthDir) + enclaveDb := getEnclaveDbForTest(t) - provider := NewGitPackageContentProvider(packageDir, packageTmpDir, enclaveDb) + provider := NewGitPackageContentProvider(packageDir, packageTmpDir, githubAuthTokenFilePath.Name(), enclaveDb) firstRunReplacePackageOptions := map[string]string{ "github.com/kurtosis-tech/sample-dependency-package": "../from-local-folder", diff --git a/core/server/commons/enclave_data_directory/enclave_data_directory.go b/core/server/commons/enclave_data_directory/enclave_data_directory.go index e9506b3364..92a5632ebc 100644 --- a/core/server/commons/enclave_data_directory/enclave_data_directory.go +++ b/core/server/commons/enclave_data_directory/enclave_data_directory.go @@ -26,6 +26,12 @@ const ( // We place the temp folder here so that the move to the final destination is atomic // Move from places outside the enclave data dir are not atomic as they're over the network tmpRepositoriesStoreDirname = "tmp-repositories" + + // Name of directory INSIDE THE ENCLAVE DATA DIR at [absMountDirPath] that contains info for authenticating GitHub operations + githubAuthStoreDirname = "github-auth" + + // Name of file within [githubAuthStoreDirname] that contains the GitHub auth token + githubAuthTokenFilename = "token.txt" ) // A directory containing all the data associated with a certain enclave (i.e. a Docker subnetwork where services are spun up) @@ -77,5 +83,11 @@ func (dir EnclaveDataDirectory) GetGitPackageContentProvider(enclaveDb *enclave_ return nil, stacktrace.Propagate(err, "An error occurred ensuring the temporary repositories store dirpath '%v' exists.", tempRepositoriesStoreDirpath) } - return git_package_content_provider.NewGitPackageContentProvider(repositoriesStoreDirpath, tempRepositoriesStoreDirpath, enclaveDb), nil + githubAuthStoreDirpath := path.Join(dir.absMountDirpath, githubAuthStoreDirname) + if err := ensureDirpathExists(githubAuthStoreDirpath); err != nil { + return nil, stacktrace.Propagate(err, "An error occurred ensuring the GitHub auth store dirpath '%v' exists.", githubAuthStoreDirpath) + } + githubAuthTokenFilepath := path.Join(dir.absMountDirpath, githubAuthStoreDirname, githubAuthTokenFilename) + + return git_package_content_provider.NewGitPackageContentProvider(repositoriesStoreDirpath, tempRepositoriesStoreDirpath, githubAuthTokenFilepath, enclaveDb), nil } diff --git a/engine/launcher/engine_server_launcher/engine_server_launcher.go b/engine/launcher/engine_server_launcher/engine_server_launcher.go index 664dd11f2a..18591ddd97 100644 --- a/engine/launcher/engine_server_launcher/engine_server_launcher.go +++ b/engine/launcher/engine_server_launcher/engine_server_launcher.go @@ -45,7 +45,7 @@ func (launcher *EngineServerLauncher) LaunchWithDefaultVersion( cloudInstanceID metrics_client.CloudInstanceID, allowedCORSOrigins *[]string, shouldStartInDebugMode bool, -) ( + githubAuthToken string) ( resultPublicIpAddr net.IP, resultPublicGrpcPortSpec *port_spec.PortSpec, resultErr error, @@ -66,7 +66,7 @@ func (launcher *EngineServerLauncher) LaunchWithDefaultVersion( cloudInstanceID, allowedCORSOrigins, shouldStartInDebugMode, - ) + githubAuthToken) if err != nil { return nil, nil, stacktrace.Propagate(err, "An error occurred launching the engine server container with default version tag '%v'", kurtosis_version.KurtosisVersion) } @@ -89,12 +89,13 @@ func (launcher *EngineServerLauncher) LaunchWithCustomVersion( cloudInstanceID metrics_client.CloudInstanceID, allowedCORSOrigins *[]string, shouldStartInDebugMode bool, -) ( + githubAuthToken string) ( resultPublicIpAddr net.IP, resultPublicGrpcPortSpec *port_spec.PortSpec, resultErr error, ) { kurtosisBackendType, kurtosisBackendConfig := backendConfigSupplier.getKurtosisBackendConfig() + argsObj, err := args.NewEngineServerArgs( grpcListenPortNum, logLevel.String(), @@ -127,6 +128,7 @@ func (launcher *EngineServerLauncher) LaunchWithCustomVersion( grpcListenPortNum, envVars, shouldStartInDebugMode, + githubAuthToken, ) if err != nil { return nil, nil, stacktrace.Propagate(err, "An error occurred launching the engine server container with environment variables '%+v'", envVars) diff --git a/engine/server/engine/enclave_manager/enclave_creator.go b/engine/server/engine/enclave_manager/enclave_creator.go index 523c898da9..d8526c2a50 100644 --- a/engine/server/engine/enclave_manager/enclave_creator.go +++ b/engine/server/engine/enclave_manager/enclave_creator.go @@ -2,7 +2,6 @@ package enclave_manager import ( "context" - "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/api_container" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/enclave" @@ -113,8 +112,7 @@ func (creator *EnclaveCreator) CreateEnclave( isCI, cloudUserID, cloudInstanceID, - shouldAPICRunInDebugMode, - ) + shouldAPICRunInDebugMode) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred launching the API container") } @@ -223,8 +221,7 @@ func (creator *EnclaveCreator) launchApiContainer( isCI, cloudUserID, cloudInstanceID, - shouldStartInDebugMode, - ) + shouldStartInDebugMode) if err != nil { return nil, stacktrace.Propagate(err, "Expected to be able to launch api container for enclave '%v' with custom version '%v', but an error occurred", enclaveUuid, apiContainerImageVersionTag) } diff --git a/engine/server/engine/enclave_manager/enclave_pool.go b/engine/server/engine/enclave_manager/enclave_pool.go index 459e7a36e4..5acd2d3f4f 100644 --- a/engine/server/engine/enclave_manager/enclave_pool.go +++ b/engine/server/engine/enclave_manager/enclave_pool.go @@ -58,7 +58,6 @@ func CreateEnclavePool( isCI bool, cloudUserID metrics_client.CloudUserID, cloudInstanceID metrics_client.CloudInstanceID, - ) (*EnclavePool, error) { //TODO the current implementation only removes the previous idle enclave, it's pending to implement the reusable feature diff --git a/engine/server/engine/main.go b/engine/server/engine/main.go index 17d8681c46..f9bac6cb38 100644 --- a/engine/server/engine/main.go +++ b/engine/server/engine/main.go @@ -177,7 +177,19 @@ func runMain() error { logFileManager := log_file_manager.NewLogFileManager(kurtosisBackend, osFs, realTime) logFileManager.StartLogFileManagement(ctx) - enclaveManager, err := getEnclaveManager(kurtosisBackend, serverArgs.KurtosisBackendType, serverArgs.ImageVersionTag, serverArgs.PoolSize, serverArgs.EnclaveEnvVars, logFileManager, serverArgs.MetricsUserID, serverArgs.DidUserAcceptSendingMetrics, serverArgs.IsCI, serverArgs.CloudUserID, serverArgs.CloudInstanceID, serverArgs.KurtosisLocalBackendConfig) + enclaveManager, err := getEnclaveManager( + kurtosisBackend, + serverArgs.KurtosisBackendType, + serverArgs.ImageVersionTag, + serverArgs.PoolSize, + serverArgs.EnclaveEnvVars, + logFileManager, + serverArgs.MetricsUserID, + serverArgs.DidUserAcceptSendingMetrics, + serverArgs.IsCI, + serverArgs.CloudUserID, + serverArgs.CloudInstanceID, + serverArgs.KurtosisLocalBackendConfig) if err != nil { return stacktrace.Propagate(err, "Failed to create an enclave manager for backend type '%v' and config '%+v'", serverArgs.KurtosisBackendType, backendConfig) } diff --git a/go.work.sum b/go.work.sum index 4f28d7c718..e69dce23b6 100644 --- a/go.work.sum +++ b/go.work.sum @@ -53,9 +53,7 @@ cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8o cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/contactcenterinsights v1.9.1 h1:hy4L0bc3fQNZZrhPjuoH62RiisD5B71/S1OZNunsTRk= cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= cloud.google.com/go/container v1.22.1 h1:WKBegIfJJc+CL2PIgNpQuvLgGW/CoGJjge5Yjpc0YuU= @@ -251,6 +249,8 @@ cloud.google.com/go/websecurityscanner v1.6.1 h1:CfEF/vZ+xXyAR3zC9iaC/QRdf1MEgS2 cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= cloud.google.com/go/workflows v1.11.1 h1:2akeQ/PgtRhrNuD/n1WvJd5zb7YyuDZrlOanBj2ihPg= cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3 h1:hJiie5Bf3QucGRa4ymsAUOxyhYwGEz1xrsVk0P8erlw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0 h1:SPOUaucgtVls75mg+X7CXigS71EnsfVUK/2CgVrwqgw= @@ -261,6 +261,8 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1 github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 h1:+vTEFqeoeur6XSq06bs+roX3YiT49gUniJK7Zky7Xjg= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= +github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= +github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/Azure/azure-sdk-for-go v56.3.0+incompatible h1:DmhwMrUIvpeoTDiWRDtNHqelNUd3Og8JCkrLHQK795c= github.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.0 h1:Ut0ZGdOwJDw0npYEg+TLlPls3Pq6JiZaP2/aGKir7Zw= @@ -298,6 +300,8 @@ github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= github.com/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= @@ -316,6 +320,8 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vaj github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +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/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc= @@ -323,6 +329,8 @@ github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/v12 v12.0.0 h1:xtZE63VWl7qLdB0JObIXvvhGjoVNrQ9ciIHG2OK5cmc= @@ -402,7 +410,6 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/casbin/casbin/v2 v2.1.2 h1:bTwon/ECRx9dwBy2ewRVr5OiqjeXSGiTUY74sDPQi/g= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= @@ -411,6 +418,10 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8= +github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs= github.com/cilium/ebpf v0.9.1 h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4= github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec h1:EdRZT3IeKQmfCSrgo8SZ8V3MEnskuJP0wCYNpe+aiXo= @@ -475,6 +486,9 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBtyYFaUT/WmOqsJjgtihT0vMI= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4= @@ -482,6 +496,8 @@ github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8l github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= +github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v24.0.4+incompatible h1:Y3bYF9ekNTm2VFz5U/0BlMdJy73D+Y1iAAZ8l63Ydzw= @@ -501,6 +517,11 @@ github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= @@ -521,11 +542,21 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db h1:gb2Z18BhTPJPpLQW github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8 h1:a9ENSRDFBUPkJ5lCgVZh26+ZbGyoVJG7yb5SSzF5H54= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= +github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= +github.com/gdamore/tcell/v2 v2.5.4 h1:TGU4tSjD3sCL788vFNeJnTdzpNKIw1H5dgLnJRQVv/k= +github.com/gdamore/tcell/v2 v2.5.4/go.mod h1:dZgRy5v4iMobMEcWNYBtREnDZAT9DYmfqIkrgEMxLyw= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -533,10 +564,10 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -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/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= @@ -549,8 +580,6 @@ github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7 h1:2hRPrmiwPrp3fQX967rNJIhQPtiGXdlQWAxKbKw3VHA= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -573,8 +602,6 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= @@ -601,6 +628,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hanwen/go-fuse/v2 v2.2.0 h1:jo5QZYmBLNcl9ovypWaQ5yXMSSV+Ch68xoC3rtZvvBM= github.com/hanwen/go-fuse/v2 v2.2.0/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= github.com/hashicorp/consul/api v1.3.0 h1:HXNYlRkkM/t+Y/Yhxtwcy02dlYwIaoxzvxPnS+cqy78= @@ -625,6 +653,8 @@ github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sL github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= +github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= +github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -643,6 +673,10 @@ github.com/intel/goresctrl v0.3.0 h1:K2D3GOzihV7xSBedGxONSlaw/un1LZgWsc9IfqipN4c github.com/intel/goresctrl v0.3.0/go.mod h1:fdz3mD85cmP9sHD8JUlrNWAxvwM86CrbmVXltEKd7zk= github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= +github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU= +github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4= +github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= +github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1 h1:ujPKutqRlJtcfWk6toYVYagwra7HQHbXOaS171b4Tg8= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -665,12 +699,15 @@ github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= @@ -692,8 +729,13 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= 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/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= +github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= +github.com/microsoft/dev-tunnels v0.0.25 h1:UlMKUI+2O8cSu4RlB52ioSyn1LthYSVkJA+CSTsdKoA= +github.com/microsoft/dev-tunnels v0.0.25/go.mod h1:frU++12T/oqxckXkDpTuYa427ncguEOodSPZcGCCrzQ= github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -713,6 +755,8 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/mmcloughlin/avo v0.5.0 h1:nAco9/aI9Lg2kiuROBY6BhCI/z0t5jEvJfjWbL8qXLU= +github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM= github.com/moby/buildkit v0.12.3 h1:cFaPVnyC0PwAP5xHHfzdU5v9rgQrCi6HnGSg3WuFKp4= github.com/moby/buildkit v0.12.3/go.mod h1:adB4y0SxxX8trnrY+oEulb48ODLqPO6pKMF0ppGcCoI= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= @@ -729,6 +773,10 @@ github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= +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/muhammadmuzzammil1998/jsonc v0.0.0-20201229145248-615b0916ca38 h1:0FrBxrkJ0hVembTb/e4EU5Ml6vLcOusAqymmYISg5Uo= +github.com/muhammadmuzzammil1998/jsonc v0.0.0-20201229145248-615b0916ca38/go.mod h1:saF2fIVw4banK0H4+/EuqfFLpRnoy5S+ECwTOCcRcSU= github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76 h1:0xuRacu/Zr+jX+KyLLPPktbwXqyOvnOPUQmMLzX1jxU= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= @@ -745,8 +793,13 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb github.com/oklog/oklog v0.3.2 h1:wVfs8F+in6nTBMkA7CbRw+zZMIB7nNM825cM1wuzoTk= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5 h1:58+kh9C6jJVXYjt8IE48G2eWl6BjwU5Gj0gqY84fy78= +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/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= @@ -797,11 +850,17 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= +github.com/rivo/tview v0.0.0-20221029100920-c4a7e501810d h1:jKIUJdMcIVGOSHi6LSqJqw9RqblyblE2ZrHvFbWR3S0= +github.com/rivo/tview v0.0.0-20221029100920-c4a7e501810d/go.mod h1:YX2wUZOcJGOIycErz2s9KvDaP0jnWwRCirQMPLPpQ+Y= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rodaine/table v1.0.1 h1:U/VwCnUxlVYxw8+NJiLIuCxA/xa6jL38MY3FYysVWWQ= +github.com/rodaine/table v1.0.1/go.mod h1:UVEtfBsflpeEcD56nF4F5AocNFta0ZuolpSVdPtlmP4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4 h1:BN/Nyn2nWMoqGRA7G7paDNDqTXE30mXGqzzybrfo05w= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -838,6 +897,9 @@ github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82 h1:LneqU9PHDsg/ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537 h1:YGaxtkYjb8mnTvtufv2LKLwCQu2/C7qFB7UtrOlTWOY= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133 h1:JtcyT0rk/9PKOdnKQzuDR+FSjh7SGtJwpgVpfZBRKlQ= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/sony/gobreaker v0.4.1 h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ= @@ -889,11 +951,16 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU= +github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os= +github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= @@ -933,35 +1000,38 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEa go4.org v0.0.0-20180809161055-417644f6feb5 h1:+hE86LblG4AyDgwMCLTE6FOlM9+qjHSYS+rKqxUVdsM= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d h1:E2M5QgjZ/Jg+ObCQAudsXxuTsLj7Nl5RV/lZcQZmKSo= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852 h1:xYq6+9AtI+xP3M4r0N1hCkHrInHDBohhquRgx9Kk6gI= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.40.0 h1:uWrpz12dpVPn7cojP82mk02XDgTJLDPc2KbVTxrWb4A= @@ -997,13 +1067,13 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQ gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919 h1:tmXTu+dfa+d9Evp8NpJdgOy6+rt8/x4yG7qPBrtNfLY= honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= k8s.io/apiserver v0.26.2 h1:Pk8lmX4G14hYqJd1poHGC08G03nIHVqdJMR0SD3IH3o=