From e7c907a99a89eb7f5f4efa77ce935fcc41d9a5b2 Mon Sep 17 00:00:00 2001 From: Pawel Kosiec Date: Fri, 19 Jan 2024 10:07:49 +0100 Subject: [PATCH] Fix Botkube version constraint during migration (#1353) * Fix Botkube version constraint during migration * Update migration test to cover multiple executors in a configuration group * Do a screenshot after button click during Cloud Slack E2E tests --- cmd/cli/cmd/migrate.go | 19 +++++++++++--- cmd/cli/docs/botkube_migrate.md | 2 +- .../cloud_slack_dev_e2e_test.go | 26 +++++++++++++------ test/e2e/migration_test.go | 9 +++++++ 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/cmd/cli/cmd/migrate.go b/cmd/cli/cmd/migrate.go index 4f475b124..81322380d 100644 --- a/cmd/cli/cmd/migrate.go +++ b/cmd/cli/cmd/migrate.go @@ -20,8 +20,8 @@ import ( "github.com/kubeshop/botkube/internal/kubex" ) -const ( - botkubeVersionConstraints = ">= 1.0, < 1.3" +var ( + botkubeMinVersionConstraint = ">= 1.0" ) // NewMigrate returns a cobra.Command for migrate the OS into Cloud. @@ -68,6 +68,7 @@ func NewMigrate() *cobra.Command { status.Infof("Checking if Botkube version %q can be migrated safely", botkubeVersionStr) + botkubeVersionConstraints := getBotkubeVersionConstraints() constraint, err := semver.NewConstraint(botkubeVersionConstraints) if err != nil { return fmt.Errorf("unable to parse Botkube semver version constraints: %w", err) @@ -143,10 +144,22 @@ func NewMigrate() *cobra.Command { flags.BoolVarP(&opts.SkipConnect, "skip-connect", "q", false, "Skips connecting to Botkube Cloud after migration") flags.BoolVar(&opts.SkipOpenBrowser, "skip-open-browser", false, "Skips opening web browser after migration") flags.BoolVarP(&opts.AutoApprove, "auto-approve", "y", false, "Skips interactive approval for upgrading Botkube installation.") - flags.StringVarP(&opts.ImageTag, "image-tag", "", "", "Botkube image tag, possible values latest, v1.2.0, ...") + flags.StringVarP(&opts.ImageTag, "image-tag", "", "", `Botkube image tag, e.g. "latest" or "v1.7.0"`) opts.ConfigExporter.RegisterFlags(flags) kubex.RegisterKubeconfigFlag(flags) return migrate } + +func getBotkubeVersionConstraints() string { + cliVer := version.Get().Version + cliVersion, err := semver.NewVersion(cliVer) + + botkubeMaxVersionConstraint := "" + if err == nil { + botkubeMaxVersionConstraint = fmt.Sprintf(", <= %s", cliVersion.String()) + } + + return fmt.Sprintf("%s%s", botkubeMinVersionConstraint, botkubeMaxVersionConstraint) +} diff --git a/cmd/cli/docs/botkube_migrate.md b/cmd/cli/docs/botkube_migrate.md index 729dc458b..2ca95c181 100644 --- a/cmd/cli/docs/botkube_migrate.md +++ b/cmd/cli/docs/botkube_migrate.md @@ -46,7 +46,7 @@ botkube migrate [OPTIONS] [flags] --cloud-env-endpoint string Endpoint environment variable name specified under Deployment for cloud installation. (default "CONFIG_PROVIDER_ENDPOINT") --cloud-env-id string Identifier environment variable name specified under Deployment for cloud installation. (default "CONFIG_PROVIDER_IDENTIFIER") -h, --help help for migrate - --image-tag string Botkube image tag, possible values latest, v1.2.0, ... + --image-tag string Botkube image tag, e.g. "latest" or "v1.7.0" --instance-name string Botkube Cloud Instance name that will be created --kubeconfig string Paths to a kubeconfig. Only required if out-of-cluster. -l, --label string Label used for identifying the Botkube pod (default "app=botkube") diff --git a/test/cloud-slack-dev-e2e/cloud_slack_dev_e2e_test.go b/test/cloud-slack-dev-e2e/cloud_slack_dev_e2e_test.go index e201ada11..ead3479c2 100644 --- a/test/cloud-slack-dev-e2e/cloud_slack_dev_e2e_test.go +++ b/test/cloud-slack-dev-e2e/cloud_slack_dev_e2e_test.go @@ -272,12 +272,12 @@ func TestCloudSlackE2E(t *testing.T) { screenshotIfShould(t, cfg, botkubePage) botkubePage.MustElementR("button > span", "Connect").MustParent().MustClick() screenshotIfShould(t, cfg, botkubePage) + // detect homepage + time.Sleep(cfg.DefaultWaitTime) // ensure the screenshots shows a view after button click + screenshotIfShould(t, cfg, botkubePage) _, err := botkubePage.ElementR(".ant-layout-content p", "All Botkube installations managed by Botkube Cloud.") - assert.NoError(t, err) // fail the test, but move on: capture the screenshot and try to disconnect Slack workspace later - if err != nil { - screenshotIfShould(t, cfg, botkubePage) - } + assert.NoError(t, err) // fail the test, but move on: try to disconnect Slack workspace later } }) @@ -669,12 +669,22 @@ func screenshotIfShould(t *testing.T, cfg E2ESlackConfig, page *rod.Page) { logMsg := fmt.Sprintf("Saving screenshot to %q", filePath) if cfg.DebugMode { - logMsg += fmt.Sprintf(" for URL %q", page.MustInfo().URL) + info, err := page.Info() + assert.NoError(t, err) + + if info != nil { + logMsg += fmt.Sprintf(" for URL %q", info.URL) + } } t.Log(logMsg) - data := page.MustScreenshot() - err := os.WriteFile(filePath, data, 0644) - require.NoError(t, err) + data, err := page.Screenshot(false, nil) + assert.NoError(t, err) + if err != nil { + return + } + + err = os.WriteFile(filePath, data, 0644) + assert.NoError(t, err) } func appendOrgIDQueryParam(t *testing.T, inURL, orgID string) string { diff --git a/test/e2e/migration_test.go b/test/e2e/migration_test.go index 281a50d85..e84ee7a14 100644 --- a/test/e2e/migration_test.go +++ b/test/e2e/migration_test.go @@ -36,6 +36,7 @@ const ( --set communications.default-group.discord.token=%s \ --set settings.clusterName=%s \ --set executors.k8s-default-tools.botkube/kubectl.enabled=true \ + --set executors.k8s-default-tools.botkube/helm.enabled=true \ --set analytics.disable=true \ --set image.tag=v9.99.9-dev \ --set plugins.repositories.botkube.url=https://storage.googleapis.com/botkube-plugins-latest/plugins-index.yaml \ @@ -387,6 +388,14 @@ func assertPlugins(t *testing.T, actual []*gqlModel.Plugin) { Configuration: "{\"defaultNamespace\":\"default\"}", Rbac: defaultRBAC, }, + { + Name: "botkube/helm", + DisplayName: "botkube/helm", + Type: "EXECUTOR", + ConfigurationName: "k8s-default-tools", + Configuration: "{\"defaultNamespace\":\"default\",\"helmCacheDir\":\"/tmp/helm/.cache\",\"helmConfigDir\":\"/tmp/helm/\",\"helmDriver\":\"secret\"}", + Rbac: defaultRBAC, + }, } assert.NotEmpty(t, actual)