Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [TKC-2683] run docker agent command #5921

Merged
merged 11 commits into from
Oct 14, 2024
Prev Previous commit
Next Next commit
feat: docker upgrade command
Signed-off-by: Vladislav Sukhin <vladislav@kubeshop.io>
  • Loading branch information
vsukhin committed Oct 11, 2024
commit 2b8afd4437a02e5a078c3a61a9ade7e634ef4d6b
69 changes: 62 additions & 7 deletions cmd/kubectl-testkube/commands/common/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ func PopulateHelmFlags(cmd *cobra.Command, options *HelmOptions) {
cmd.Flags().BoolVar(&options.EmbeddedNATS, "embedded-nats", false, "embedded NATS server in agent")
}

func PopulateLoginDataToContext(orgID, envID, token, refreshToken string, options HelmOptions, cfg config.Data) error {
func PopulateLoginDataToContext(orgID, envID, token, refreshToken, dockerContainerName string, options HelmOptions, cfg config.Data) error {
if options.Master.AgentToken != "" {
cfg.CloudContext.AgentKey = options.Master.AgentToken
}
Expand All @@ -319,6 +319,7 @@ func PopulateLoginDataToContext(orgID, envID, token, refreshToken string, option
if refreshToken != "" {
cfg.CloudContext.RefreshToken = refreshToken
}
cfg.CloudContext.DockerContainerName = dockerContainerName

cfg, err := PopulateOrgAndEnvNames(cfg, orgID, envID, options.Master.URIs.Api)
if err != nil {
Expand Down Expand Up @@ -777,7 +778,7 @@ func RunDockerCommand(args []string) (output string, cliErr *CLIError) {
return string(out), nil
}

func DockerRunTestkubeAgent(options HelmOptions, cfg config.Data, containerName, dockerImage string) *CLIError {
func DockerRunTestkubeAgent(options HelmOptions, cfg config.Data, dockerContainerName, dockerImage string) *CLIError {
// use config if set
if cfg.CloudContext.AgentKey != "" && options.Master.AgentToken == "" {
options.Master.AgentToken = cfg.CloudContext.AgentKey
Expand All @@ -791,7 +792,7 @@ func DockerRunTestkubeAgent(options HelmOptions, cfg config.Data, containerName,
errors.New("agent key is required"))
}

args := prepareTestkubeProDockerArgs(options, containerName, dockerImage)
args := prepareTestkubeProDockerArgs(options, dockerContainerName, dockerImage)
output, err := RunDockerCommand(args)
if err != nil {
return err
Expand All @@ -806,10 +807,10 @@ func DockerRunTestkubeAgent(options HelmOptions, cfg config.Data, containerName,
}

// prepareTestkubeProDockerArgs prepares docker arguments for Testkube Pro running.
func prepareTestkubeProDockerArgs(options HelmOptions, containerName, dockerImage string) []string {
func prepareTestkubeProDockerArgs(options HelmOptions, dockerContainerName, dockerImage string) []string {
args := []string{
"run",
"--name", containerName,
"--name", dockerContainerName,
"--privileged",
"-d",
"-e", "CLOUD_URL=" + options.Master.URIs.Agent,
Expand All @@ -820,7 +821,33 @@ func prepareTestkubeProDockerArgs(options HelmOptions, containerName, dockerImag
return args
}

func StreamDockerLogs(containerName string) *CLIError {
// prepareTestkubeUpgradeDockerArgs prepares docker arguments for Testkube Upgrade running.
func prepareTestkubeUpgradeDockerArgs(options HelmOptions, dockerContainerName string) []string {
args := []string{
"exec",
dockerContainerName,
"helm",
"upgrade",
"testkube",
"testkube/testkube",
"--namespace",
"testkube",
"--set",
"testkube-api.minio.enabled=false",
"--set",
"mongodb.enabled=false",
"--set",
"testkube-dashboard.enabled=false",
"--set",
"testkube-api.cloud.key=" + options.Master.AgentToken,
"--set",
"testkube-api.cloud.url=" + options.Master.URIs.Agent,
}

return args
}

func StreamDockerLogs(dockerContainerName string) *CLIError {
// Create a Docker client
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
Expand All @@ -841,7 +868,7 @@ func StreamDockerLogs(containerName string) *CLIError {
}

// Fetch logs from the container
logs, err := cli.ContainerLogs(ctx, containerName, opts)
logs, err := cli.ContainerLogs(ctx, dockerContainerName, opts)
if err != nil {
return NewCLIError(
TKErrDockerLogStreamingFailed,
Expand Down Expand Up @@ -886,3 +913,31 @@ func StreamDockerLogs(containerName string) *CLIError {

return nil
}

func DockerUpgradeTestkubeAgent(options HelmOptions, cfg config.Data) *CLIError {
// use config if set
if cfg.CloudContext.AgentKey != "" && options.Master.AgentToken == "" {
options.Master.AgentToken = cfg.CloudContext.AgentKey
}

if options.Master.AgentToken == "" {
return NewCLIError(
TKErrInvalidInstallConfig,
"Invalid install config",
"Provide the agent token by setting the '--agent-token' flag",
errors.New("agent key is required"))
}

args := prepareTestkubeUpgradeDockerArgs(options, cfg.CloudContext.DockerContainerName)
output, err := RunDockerCommand(args)
if err != nil {
return err
}

ui.Debug("Docker command output:")
ui.Debug("Arguments", args...)

ui.Debug("Docker run testkube output", output)

return nil
}
2 changes: 1 addition & 1 deletion cmd/kubectl-testkube/commands/pro/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func NewConnectCmd() *cobra.Command {
token, refreshToken, err = common.LoginUser(opts.Master.URIs.Auth)
ui.ExitOnError("user login", err)
}
err = common.PopulateLoginDataToContext(opts.Master.OrgId, opts.Master.EnvId, token, refreshToken, opts, cfg)
err = common.PopulateLoginDataToContext(opts.Master.OrgId, opts.Master.EnvId, token, refreshToken, "", opts, cfg)

ui.ExitOnError("Setting Pro environment context", err)

Expand Down
17 changes: 9 additions & 8 deletions cmd/kubectl-testkube/commands/pro/docker.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pro

import (
"errors"
"os"

"github.com/pterm/pterm"
Expand All @@ -13,7 +14,7 @@ import (

func NewDockerCmd() *cobra.Command {
var noLogin bool // ignore ask for login
var containerName, dockerImage string
var dockerContainerName, dockerImage string
var options common.HelmOptions

cmd := &cobra.Command{
Expand Down Expand Up @@ -48,7 +49,7 @@ func NewDockerCmd() *cobra.Command {

dockerInfo, cliErr := common.RunDockerCommand([]string{"info"})
if cliErr != nil {
sendErrTelemetry(cmd, cfg, "docker_info", err)
sendErrTelemetry(cmd, cfg, "docker_info", cliErr)
common.HandleCLIError(cliErr)
}
ui.Alert("Current docker info:", dockerInfo)
Expand All @@ -57,7 +58,7 @@ func NewDockerCmd() *cobra.Command {
ok := ui.Confirm("Do you want to continue?")
if !ok {
ui.Errf("Testkube Docker Agent running cancelled")
sendErrTelemetry(cmd, cfg, "user_cancel", err)
sendErrTelemetry(cmd, cfg, "user_cancel", errors.New("user cancelled agent running"))
return
}
}
Expand All @@ -69,15 +70,15 @@ func NewDockerCmd() *cobra.Command {
spinner = ui.NewSpinner("Running Testkube Docker Agent")
}

if cliErr := common.DockerRunTestkubeAgent(options, cfg, containerName, dockerImage); cliErr != nil {
if cliErr := common.DockerRunTestkubeAgent(options, cfg, dockerContainerName, dockerImage); cliErr != nil {
if spinner != nil {
spinner.Fail()
}
sendErrTelemetry(cmd, cfg, "docker_run", cliErr)
common.HandleCLIError(cliErr)
}

if cliErr := common.StreamDockerLogs(containerName); cliErr != nil {
if cliErr := common.StreamDockerLogs(dockerContainerName); cliErr != nil {
if spinner != nil {
spinner.Fail()
}
Expand Down Expand Up @@ -107,7 +108,7 @@ func NewDockerCmd() *cobra.Command {
sendErrTelemetry(cmd, cfg, "login", err)
ui.ExitOnError("user login", err)
}
err = common.PopulateLoginDataToContext(options.Master.OrgId, options.Master.EnvId, token, refreshToken, options, cfg)
err = common.PopulateLoginDataToContext(options.Master.OrgId, options.Master.EnvId, token, refreshToken, dockerContainerName, options, cfg)
if err != nil {
sendErrTelemetry(cmd, cfg, "setting_context", err)
ui.ExitOnError("Setting Pro environment context", err)
Expand All @@ -120,8 +121,8 @@ func NewDockerCmd() *cobra.Command {
common.PopulateMasterFlags(cmd, &options)

cmd.Flags().BoolVarP(&noLogin, "no-login", "", false, "Ignore login prompt, set existing token later by `testkube set context`")
cmd.Flags().StringVar(&containerName, "container-name", "testkube-agent", "container name for Testkube Docker Agent")
cmd.Flags().StringVar(&dockerImage, "docker-image", "kubeshop/testkube-agent:latest", "docker image for Testkube Docker Agent")
cmd.Flags().StringVar(&dockerContainerName, "docker-container", "testkube-agent", "Docker container name for Testkube Docker Agent")
cmd.Flags().StringVar(&dockerImage, "docker-image", "kubeshop/testkube-agent:latest", "Docker image for Testkube Docker Agent")

return cmd
}
2 changes: 1 addition & 1 deletion cmd/kubectl-testkube/commands/pro/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func NewInitCmd() *cobra.Command {
sendErrTelemetry(cmd, cfg, "login", err)
ui.ExitOnError("user login", err)
}
err = common.PopulateLoginDataToContext(options.Master.OrgId, options.Master.EnvId, token, refreshToken, options, cfg)
err = common.PopulateLoginDataToContext(options.Master.OrgId, options.Master.EnvId, token, refreshToken, "", options, cfg)
if err != nil {
sendErrTelemetry(cmd, cfg, "setting_context", err)
ui.ExitOnError("Setting Pro environment context", err)
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubectl-testkube/commands/pro/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func NewLoginCmd() *cobra.Command {
ui.ExitOnError("getting environment", err)
}

err = common.PopulateLoginDataToContext(orgID, envID, token, refreshToken, opts, cfg)
err = common.PopulateLoginDataToContext(orgID, envID, token, refreshToken, "", opts, cfg)
ui.ExitOnError("saving config file", err)

ui.Success("Your config was updated with new values")
Expand Down
38 changes: 30 additions & 8 deletions cmd/kubectl-testkube/commands/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

func NewUpgradeCmd() *cobra.Command {
var options common.HelmOptions
var dockerContainerName string

cmd := &cobra.Command{
Use: "upgrade",
Expand All @@ -32,17 +33,32 @@ func NewUpgradeCmd() *cobra.Command {
cfg.ContextType = config.ContextTypeCloud
}

if cmd.Flags().Changed("docker-container") {
cfg.CloudContext.DockerContainerName = dockerContainerName
}

if !options.NoConfirm {
ui.Warn("This will upgrade Testkube to the latest version. This may take a few minutes.")
ui.Warn("Please be sure you're on valid kubectl context before continuing!")
ui.NL()
if cfg.CloudContext.DockerContainerName != "" {
ui.Warn("Please be sure you have Docker service running before continuing and can run containers in privileged mode!")

currentContext, cliErr := common.GetCurrentKubernetesContext()
common.HandleCLIError(cliErr)
dockerInfo, cliErr := common.RunDockerCommand([]string{"info"})
if cliErr != nil {
common.HandleCLIError(cliErr)
}

ui.ExitOnError("getting current context", err)
ui.Alert("Current kubectl context:", currentContext)
ui.NL()
ui.Alert("Current docker info:", dockerInfo)
ui.NL()
} else {
ui.Warn("Please be sure you're on valid kubectl context before continuing!")

currentContext, cliErr := common.GetCurrentKubernetesContext()
common.HandleCLIError(cliErr)

ui.ExitOnError("getting current context", err)
ui.Alert("Current kubectl context:", currentContext)
ui.NL()
}

if ui.IsVerbose() && cfg.ContextType == config.ContextTypeCloud {
ui.Info("Your Testkube is in 'cloud' mode with following context")
Expand All @@ -62,7 +78,11 @@ func NewUpgradeCmd() *cobra.Command {

if cfg.ContextType == config.ContextTypeCloud {
ui.Info("Testkube Pro agent upgrade started")
err = common.HelmUpgradeOrInstallTestkubeAgent(options, cfg, false)
if cfg.CloudContext.DockerContainerName != "" {
err = common.DockerUpgradeTestkubeAgent(options, cfg)
} else {
err = common.HelmUpgradeOrInstallTestkubeAgent(options, cfg, false)
}
ui.ExitOnError("Upgrading Testkube Pro Agent", err)
err = common.PopulateAgentDataToContext(options, cfg)
ui.ExitOnError("Storing agent data in context", err)
Expand All @@ -86,5 +106,7 @@ func NewUpgradeCmd() *cobra.Command {
common.PopulateHelmFlags(cmd, &options)
common.PopulateMasterFlags(cmd, &options)

cmd.Flags().StringVar(&dockerContainerName, "docker-container", "testkube-agent", "Docker container name for Testkube Docker Agent")

return cmd
}
25 changes: 13 additions & 12 deletions cmd/kubectl-testkube/config/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@ const (
)

type CloudContext struct {
EnvironmentId string `json:"environment,omitempty"`
EnvironmentName string `json:"environmentName,omitempty"`
OrganizationId string `json:"organization,omitempty"`
OrganizationName string `json:"organizationName,omitempty"`
ApiKey string `json:"apiKey,omitempty"`
RefreshToken string `json:"refreshToken,omitempty"`
ApiUri string `json:"apiUri,omitempty"`
AgentKey string `json:"agentKey,omitempty"`
AgentUri string `json:"agentUri,omitempty"`
RootDomain string `json:"rootDomain,omitempty"`
UiUri string `json:"uiUri,omitempty"`
TokenType string `json:"tokenType,omitempty"`
EnvironmentId string `json:"environment,omitempty"`
EnvironmentName string `json:"environmentName,omitempty"`
OrganizationId string `json:"organization,omitempty"`
OrganizationName string `json:"organizationName,omitempty"`
ApiKey string `json:"apiKey,omitempty"`
RefreshToken string `json:"refreshToken,omitempty"`
ApiUri string `json:"apiUri,omitempty"`
AgentKey string `json:"agentKey,omitempty"`
AgentUri string `json:"agentUri,omitempty"`
RootDomain string `json:"rootDomain,omitempty"`
UiUri string `json:"uiUri,omitempty"`
TokenType string `json:"tokenType,omitempty"`
DockerContainerName string `json:"dockerContainerName,omitempty"`
}

type Data struct {
Expand Down
Loading