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=