diff --git a/cmd/kubectl-testkube/commands/common.go b/cmd/kubectl-testkube/commands/common.go new file mode 100644 index 00000000000..80a8b2a5f61 --- /dev/null +++ b/cmd/kubectl-testkube/commands/common.go @@ -0,0 +1,96 @@ +package commands + +import ( + "fmt" + "os/exec" + "strings" + + "github.com/kubeshop/testkube/cmd/kubectl-testkube/commands/common" + "github.com/kubeshop/testkube/internal/migrations" + "github.com/kubeshop/testkube/pkg/process" + "github.com/kubeshop/testkube/pkg/ui" + "github.com/spf13/cobra" +) + +func RunMigrations(cmd *cobra.Command) (hasMigrations bool, err error) { + client, _ := common.GetClient(cmd) + info, err := client.GetServerInfo() + ui.ExitOnError("getting server info", err) + + if info.Version == "" { + ui.Failf("Can't detect cluster version") + } + + migrator := migrations.Migrator + ui.Info("Available migrations for", info.Version) + migrations := migrator.GetValidMigrations(info.Version) + if len(migrations) == 0 { + ui.Warn("No migrations available for", info.Version) + return false, nil + } + + for _, migration := range migrations { + fmt.Printf("- %+v - %s\n", migration.Version(), migration.Info()) + } + + return true, migrator.Run(info.Version) +} + +func HelmUpgradeOrInstalTestkube(name, namespace, chart string, noDashboard, noMinio, noJetstack bool) error { + helmPath, err := exec.LookPath("helm") + if err != nil { + return err + } + + if !noJetstack { + _, err = process.Execute("kubectl", "get", "crds", "certificates.cert-manager.io") + if err != nil && !strings.Contains(err.Error(), "Error from server (NotFound)") { + return err + } + + if err != nil { + ui.Info("Helm installing jetstack cert manager") + _, err = process.Execute(helmPath, "repo", "add", "jetstack", "https://charts.jetstack.io") + if err != nil && !strings.Contains(err.Error(), "Error: repository name (jetstack) already exists") { + return err + } + + _, err = process.Execute(helmPath, "repo", "update") + if err != nil { + return err + } + + command := []string{"upgrade", "--install", "--create-namespace", "--namespace", namespace, "--set", "installCRDs=true"} + command = append(command, "jetstack", "jetstack/cert-manager") + + out, err := process.Execute(helmPath, command...) + if err != nil { + return err + } + + ui.Info("Helm install jetstack output", string(out)) + } + } + + ui.Info("Helm installing testkube framework") + _, err = process.Execute(helmPath, "repo", "add", "kubeshop", "https://kubeshop.github.io/helm-charts") + if err != nil && !strings.Contains(err.Error(), "Error: repository name (kubeshop) already exists, please specify a different name") { + ui.WarnOnError("adding testkube repo", err) + } + + _, err = process.Execute(helmPath, "repo", "update") + ui.ExitOnError("updating helm repositories", err) + + command := []string{"upgrade", "--install", "--create-namespace", "--namespace", namespace} + command = append(command, "--set", fmt.Sprintf("api-server.minio.enabled=%t", !noMinio)) + command = append(command, "--set", fmt.Sprintf("testkube-dashboard.enabled=%t", !noDashboard)) + command = append(command, name, chart) + + out, err := process.Execute(helmPath, command...) + if err != nil { + return err + } + + ui.Info("Helm install testkube output", string(out)) + return nil +} diff --git a/cmd/kubectl-testkube/commands/install.go b/cmd/kubectl-testkube/commands/install.go index 544617035ff..a134a8494bf 100644 --- a/cmd/kubectl-testkube/commands/install.go +++ b/cmd/kubectl-testkube/commands/install.go @@ -1,82 +1,25 @@ package commands import ( - "fmt" - "os/exec" - "strings" - - "github.com/kubeshop/testkube/pkg/process" "github.com/kubeshop/testkube/pkg/ui" "github.com/spf13/cobra" ) -var ( - noDashboard bool - noMinio bool - noJetstack bool -) - func NewInstallCmd() *cobra.Command { - var chart, name, namespace string + var ( + noDashboard bool + noMinio bool + noJetstack bool + chart, name, namespace string + ) + cmd := &cobra.Command{ - Use: "install", - Short: "Install Helm chart registry in current kubectl context", - Long: `Install can be configured with use of particular `, - Aliases: []string{"update", "upgrade"}, + Use: "install", + Short: "Install Helm chart registry in current kubectl context", + Long: `Install can be configured with use of particular `, Run: func(cmd *cobra.Command, args []string) { - - ui.Verbose = true - ui.Logo() - var err error - - helmPath, err := exec.LookPath("helm") - ui.ExitOnError("checking helm installation path", err) - - if !noJetstack { - _, err = process.Execute("kubectl", "get", "crds", "certificates.cert-manager.io") - if err != nil && !strings.Contains(err.Error(), "Error from server (NotFound)") { - ui.ExitOnError("checking cert manager installation", err) - } - - if err != nil { - ui.Info("Helm installing jetstack cert manager") - _, err = process.Execute(helmPath, "repo", "add", "jetstack", "https://charts.jetstack.io") - if err != nil && !strings.Contains(err.Error(), "Error: repository name (jetstack) already exists") { - ui.ExitOnError("adding jetstack repo", err) - } - - _, err = process.Execute(helmPath, "repo", "update") - ui.ExitOnError("updating helm repositories", err) - - command := []string{"upgrade", "--install", "--create-namespace", "--namespace", namespace, "--set", "installCRDs=true"} - command = append(command, "jetstack", "jetstack/cert-manager") - - out, err := process.Execute(helmPath, command...) - - ui.ExitOnError("executing helm install jetstack", err) - ui.Info("Helm install jetstack output", string(out)) - } - } - - ui.Info("Helm installing testkube framework") - _, err = process.Execute(helmPath, "repo", "add", "kubeshop", "https://kubeshop.github.io/helm-charts") - if err != nil && !strings.Contains(err.Error(), "Error: repository name (kubeshop) already exists, please specify a different name") { - ui.WarnOnError("adding testkube repo", err) - } - - _, err = process.Execute(helmPath, "repo", "update") - ui.ExitOnError("updating helm repositories", err) - - command := []string{"upgrade", "--install", "--create-namespace", "--namespace", namespace} - command = append(command, "--set", fmt.Sprintf("api-server.minio.enabled=%t", !noMinio)) - command = append(command, "--set", fmt.Sprintf("testkube-dashboard.enabled=%t", !noDashboard)) - command = append(command, name, chart) - - out, err := process.Execute(helmPath, command...) - - ui.ExitOnError("executing helm install testkube", err) - ui.Info("Helm install testkube output", string(out)) + HelmUpgradeOrInstalTestkube(name, namespace, chart, noDashboard, noMinio, noJetstack) }, } diff --git a/cmd/kubectl-testkube/commands/migrate.go b/cmd/kubectl-testkube/commands/migrate.go index 9ac0f02e196..a1c3b02e8cd 100644 --- a/cmd/kubectl-testkube/commands/migrate.go +++ b/cmd/kubectl-testkube/commands/migrate.go @@ -1,10 +1,6 @@ package commands import ( - "fmt" - - "github.com/kubeshop/testkube/cmd/kubectl-testkube/commands/common" - "github.com/kubeshop/testkube/internal/migrations" "github.com/kubeshop/testkube/pkg/ui" "github.com/spf13/cobra" ) @@ -13,33 +9,15 @@ func NewMigrateCmd() *cobra.Command { var namespace string cmd := &cobra.Command{ Use: "migrate", - Short: "migrate command", - Long: `migrate command manages migrations`, + Short: "manual migrate command", + Long: `migrate command will run migrations greater or equals current version`, Run: func(cmd *cobra.Command, args []string) { ui.Logo() - - client, _ := common.GetClient(cmd) - info, err := client.GetServerInfo() - ui.ExitOnError("getting server info", err) - - if info.Version == "" { - ui.Failf("Can't detect cluster version") - } - - migrator := migrations.Migrator - ui.Info("Available migrations for", info.Version) - migrations := migrator.GetValidMigrations(info.Version) - if len(migrations) == 0 { - ui.Warn("No migrations available for", info.Version) - } - - for _, migration := range migrations { - fmt.Printf("- %+v - %s\n", migration.Version(), migration.Info()) + hasMigrations, err := RunMigrations(cmd) + ui.ExitOnError("Running migrations", err) + if hasMigrations { + ui.Success("All migrations executed successfully") } - - err = migrator.Run(info.Version) - ui.ExitOnError("running migrations", err) - ui.Success("All migrations executed successfully") }, } diff --git a/cmd/kubectl-testkube/commands/root.go b/cmd/kubectl-testkube/commands/root.go index 89e6cded35f..e201baff8ee 100644 --- a/cmd/kubectl-testkube/commands/root.go +++ b/cmd/kubectl-testkube/commands/root.go @@ -24,6 +24,7 @@ func init() { RootCmd.AddCommand(NewCRDsCmd()) RootCmd.AddCommand(NewVersionCmd()) RootCmd.AddCommand(NewInstallCmd()) + RootCmd.AddCommand(NewUpgradeCmd()) RootCmd.AddCommand(NewUninstallCmd()) RootCmd.AddCommand(NewDashboardCmd()) RootCmd.AddCommand(NewExecutorsCmd()) diff --git a/cmd/kubectl-testkube/commands/uninstall.go b/cmd/kubectl-testkube/commands/uninstall.go index e94690d471d..29f55476be5 100644 --- a/cmd/kubectl-testkube/commands/uninstall.go +++ b/cmd/kubectl-testkube/commands/uninstall.go @@ -8,7 +8,6 @@ import ( func NewUninstallCmd() *cobra.Command { var name, namespace string - var removeCRDs bool cmd := &cobra.Command{ Use: "uninstall", @@ -21,17 +20,11 @@ func NewUninstallCmd() *cobra.Command { _, err := process.Execute("helm", "uninstall", "--namespace", namespace, name) ui.PrintOnError("uninstalling testkube", err) - - if removeCRDs { - _, err = process.Execute("kubectl", "delete", "crds", "--namespace", namespace, "scripts.tests.testkube.io", "tests.tests.testkube.io", "executors.executor.testkube.io") - ui.PrintOnError("uninstalling CRDs", err) - } }, } cmd.Flags().StringVar(&name, "name", "testkube", "installation name") cmd.Flags().StringVar(&namespace, "namespace", "testkube", "namespace where to install") - cmd.Flags().BoolVar(&removeCRDs, "remove-crds", false, "wipe out Executors and Scripts CRDs") return cmd } diff --git a/cmd/kubectl-testkube/commands/upgrade.go b/cmd/kubectl-testkube/commands/upgrade.go new file mode 100644 index 00000000000..17a70306f19 --- /dev/null +++ b/cmd/kubectl-testkube/commands/upgrade.go @@ -0,0 +1,45 @@ +package commands + +import ( + "github.com/kubeshop/testkube/pkg/ui" + "github.com/spf13/cobra" +) + +func NewUpgradeCmd() *cobra.Command { + var ( + noDashboard bool + noMinio bool + noJetstack bool + chart, name, namespace string + ) + + cmd := &cobra.Command{ + Use: "upgrade", + Short: "Upgrade Helm chart and run migrations", + Long: `Upgrade can be configured with use of particular `, + Aliases: []string{"update"}, + Run: func(cmd *cobra.Command, args []string) { + ui.Logo() + + hasMigrations, err := RunMigrations(cmd) + ui.ExitOnError("Running migrations", err) + if hasMigrations { + ui.Success("All migrations executed successfully") + } + + err = HelmUpgradeOrInstalTestkube(name, namespace, chart, noDashboard, noMinio, noJetstack) + ui.ExitOnError("installing Testkube", err) + + }, + } + + cmd.Flags().StringVar(&chart, "chart", "kubeshop/testkube", "chart name") + cmd.Flags().StringVar(&name, "name", "testkube", "installation name") + cmd.Flags().StringVar(&namespace, "namespace", "testkube", "namespace where to install") + + cmd.Flags().BoolVar(&noMinio, "no-minio", false, "don't install MinIO") + cmd.Flags().BoolVar(&noDashboard, "no-dashboard", false, "don't install dashboard") + cmd.Flags().BoolVar(&noJetstack, "no-jetstack", false, "don't install Jetstack") + + return cmd +}