Skip to content

Commit

Permalink
Improve migrate flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Josef Karasek committed Aug 17, 2023
1 parent 3b92a12 commit fb16ffe
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 124 deletions.
18 changes: 8 additions & 10 deletions cmd/cli/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/kubeshop/botkube/internal/cli"
"github.com/kubeshop/botkube/internal/cli/heredoc"
"github.com/kubeshop/botkube/internal/cli/install"
"github.com/kubeshop/botkube/internal/cli/install/helm"
"github.com/kubeshop/botkube/internal/kubex"
)

Expand All @@ -20,8 +21,8 @@ func NewInstall() *cobra.Command {

installCmd := &cobra.Command{
Use: "install [OPTIONS]",
Short: "install Botkube into cluster",
Long: "Use this command to install the Botkube agent.",
Short: "install or upgrade Botkube in k8s cluster",
Long: "Use this command to install or upgrade the Botkube agent.",
Aliases: []string{"instl", "deploy"},
Example: heredoc.WithCLIName(`
# Install latest stable Botkube version
Expand All @@ -34,9 +35,6 @@ func NewInstall() *cobra.Command {
<cli> install --repo @local`, cli.Name),
RunE: func(cmd *cobra.Command, args []string) error {
config, err := kubex.LoadRestConfigWithMetaInformation()
if err != nil {
return err
}
if err != nil {
return errors.Wrap(err, "while creating k8s config")
}
Expand All @@ -52,11 +50,11 @@ func NewInstall() *cobra.Command {
flags.BoolVarP(&opts.Watch, "watch", "w", true, "Watches the status of the Botkube installation until it finish or the defined `--timeout` occurs.")

// common params for install and upgrade operation
flags.StringVar(&opts.HelmParams.Version, "version", install.LatestVersionTag, "Botkube version. Possible values @latest, 1.2.0, ...")
flags.StringVar(&opts.HelmParams.Namespace, "namespace", install.Namespace, "Botkube installation namespace.")
flags.StringVar(&opts.HelmParams.ReleaseName, "release-name", install.ReleaseName, "Botkube Helm chart release name.")
flags.StringVar(&opts.HelmParams.ChartName, "chart-name", install.HelmChartName, "Botkube Helm chart name.")
flags.StringVar(&opts.HelmParams.RepoLocation, "repo", install.HelmRepoStable, fmt.Sprintf("Botkube Helm chart repository location. It can be relative path to current working directory or URL. Use %s tag to select repository which holds the stable Helm chart versions.", install.StableVersionTag))
flags.StringVar(&opts.HelmParams.Version, "version", helm.LatestVersionTag, "Botkube version. Possible values @latest, 1.2.0, ...")
flags.StringVar(&opts.HelmParams.Namespace, "namespace", helm.Namespace, "Botkube installation namespace.")
flags.StringVar(&opts.HelmParams.ReleaseName, "release-name", helm.ReleaseName, "Botkube Helm chart release name.")
flags.StringVar(&opts.HelmParams.ChartName, "chart-name", helm.HelmChartName, "Botkube Helm chart name.")
flags.StringVar(&opts.HelmParams.RepoLocation, "repo", helm.HelmRepoStable, fmt.Sprintf("Botkube Helm chart repository location. It can be relative path to current working directory or URL. Use %s tag to select repository which holds the stable Helm chart versions.", helm.StableVersionTag))
flags.BoolVar(&opts.HelmParams.DryRun, "dry-run", false, "Simulate an install")
flags.BoolVar(&opts.HelmParams.Force, "force", false, "Force resource updates through a replacement strategy")
flags.BoolVar(&opts.HelmParams.DisableHooks, "no-hooks", false, "Disable pre/post install/upgrade hooks")
Expand Down
13 changes: 11 additions & 2 deletions cmd/cli/cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/fatih/color"
semver "github.com/hashicorp/go-version"
"github.com/pkg/browser"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"go.szostok.io/version"
corev1 "k8s.io/api/core/v1"
Expand All @@ -17,6 +18,7 @@ import (
"github.com/kubeshop/botkube/internal/cli/heredoc"
"github.com/kubeshop/botkube/internal/cli/migrate"
"github.com/kubeshop/botkube/internal/cli/printer"
"github.com/kubeshop/botkube/internal/kubex"
)

const (
Expand Down Expand Up @@ -54,13 +56,18 @@ func NewMigrate() *cobra.Command {
`, cli.Name),
RunE: func(cmd *cobra.Command, args []string) (err error) {
k8sConfig, err := kubex.LoadRestConfigWithMetaInformation()
if err != nil {
return errors.Wrap(err, "while creating k8s config")
}

status := printer.NewStatus(cmd.OutOrStdout(), "Migrating Botkube installation to Cloud")
defer func() {
status.End(err == nil)
}()

status.Step("Fetching Botkube configuration")
cfg, pod, err := migrate.GetConfigFromCluster(cmd.Context(), opts)
cfg, pod, err := migrate.GetConfigFromCluster(cmd.Context(), k8sConfig.K8s, opts)
if err != nil {
return err
}
Expand Down Expand Up @@ -107,7 +114,7 @@ func NewMigrate() *cobra.Command {
}

status.Step("Run Botkube migration")
instanceID, err := migrate.Run(cmd.Context(), status, cfg, opts)
instanceID, err := migrate.Run(cmd.Context(), status, cfg, k8sConfig, opts)
if err != nil {
return err
}
Expand All @@ -134,6 +141,8 @@ func NewMigrate() *cobra.Command {
}

flags := login.Flags()
kubex.RegisterKubeconfigFlag(flags)
flags.DurationVar(&opts.Timeout, "timeout", 10*time.Minute, `Maximum time during which the Botkube installation is being watched, where "0" means "infinite". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
flags.StringVar(&opts.Token, "token", "", "Botkube Cloud authentication token")
flags.StringVar(&opts.InstanceName, "instance-name", "", "Botkube Cloud Instance name that will be created")
flags.StringVar(&opts.CloudAPIURL, "cloud-api-url", "https://api.botkube.io/graphql", "Botkube Cloud API URL")
Expand Down
6 changes: 3 additions & 3 deletions cmd/cli/cmd/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

"github.com/kubeshop/botkube/internal/cli"
"github.com/kubeshop/botkube/internal/cli/heredoc"
"github.com/kubeshop/botkube/internal/cli/install"
"github.com/kubeshop/botkube/internal/cli/install/helm"
"github.com/kubeshop/botkube/internal/cli/uninstall"
"github.com/kubeshop/botkube/internal/kubex"
)
Expand Down Expand Up @@ -46,8 +46,8 @@ func NewUninstall() *cobra.Command {

kubex.RegisterKubeconfigFlag(flags)

flags.StringVar(&opts.HelmParams.ReleaseName, "release-name", install.ReleaseName, "Botkube Helm release name.")
flags.StringVar(&opts.HelmParams.ReleaseNamespace, "namespace", install.Namespace, "Botkube namespace.")
flags.StringVar(&opts.HelmParams.ReleaseName, "release-name", helm.ReleaseName, "Botkube Helm release name.")
flags.StringVar(&opts.HelmParams.ReleaseNamespace, "namespace", helm.Namespace, "Botkube namespace.")
flags.BoolVarP(&opts.AutoApprove, "auto-approve", "y", false, "Skips interactive approval for deletion.")

flags.BoolVar(&opts.HelmParams.DryRun, "dry-run", false, "simulate a uninstall")
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ require (
github.com/stretchr/testify v1.8.4
github.com/vrischmann/envconfig v1.3.0
github.com/xeipuuv/gojsonschema v1.2.0
github.com/xyproto/randomstring v1.0.5
go.szostok.io/version v1.2.0
golang.org/x/exp v0.0.0-20230307190834-24139beb5833
golang.org/x/oauth2 v0.8.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,8 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJu
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
19 changes: 0 additions & 19 deletions internal/cli/install/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,6 @@ import (
"github.com/kubeshop/botkube/internal/cli/install/helm"
)

const (
// StableVersionTag tag used to select stable Helm chart repository.
StableVersionTag = "@stable"
// LocalVersionTag tag used to select local Helm chart repository.
LocalVersionTag = "@local"
// LatestVersionTag tag used to select the latest version from the Helm chart repository.
LatestVersionTag = "@latest"
// Namespace in which Botkube is installed.
Namespace = "botkube"
// ReleaseName defines Botkube Helm chart release name.
ReleaseName = "botkube"
// HelmRepoStable URL of the stable Botkube Helm charts repository.
HelmRepoStable = "https://charts.botkube.io/"
// HelmChartName represents Botkube Helm chart name in a given Helm repository.
HelmChartName = "botkube"
// LocalChartsPath path to Helm charts in botkube repository.
LocalChartsPath = "./helm/"
)

// Config holds parameters for Botkube installation on cluster.
type Config struct {
Kubeconfig string
Expand Down
19 changes: 19 additions & 0 deletions internal/cli/install/helm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ import (
"helm.sh/helm/v3/pkg/cli/values"
)

const (
// StableVersionTag tag used to select stable Helm chart repository.
StableVersionTag = "@stable"
// LocalVersionTag tag used to select local Helm chart repository.
LocalVersionTag = "@local"
// LatestVersionTag tag used to select the latest version from the Helm chart repository.
LatestVersionTag = "@latest"
// Namespace in which Botkube is installed.
Namespace = "botkube"
// ReleaseName defines Botkube Helm chart release name.
ReleaseName = "botkube"
// HelmRepoStable URL of the stable Botkube Helm charts repository.
HelmRepoStable = "https://charts.botkube.io/"
// HelmChartName represents Botkube Helm chart name in a given Helm repository.
HelmChartName = "botkube"
// LocalChartsPath path to Helm charts in botkube repository.
LocalChartsPath = "./helm/"
)

// Config holds Helm configuration parameters.
type Config struct {
ReleaseName string
Expand Down
16 changes: 8 additions & 8 deletions internal/cli/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,21 @@ func Install(ctx context.Context, w io.Writer, k8sCfg *kubex.ConfigWithMeta, opt
}()

switch opts.HelmParams.RepoLocation {
case StableVersionTag:
status.Debugf("Resolved %s tag into %s...", StableVersionTag, HelmRepoStable)
opts.HelmParams.RepoLocation = HelmRepoStable
case LocalVersionTag:
status.Debugf("Resolved %s tag into %s...", LocalVersionTag, LocalChartsPath)
opts.HelmParams.RepoLocation = LocalChartsPath
case helm.StableVersionTag:
status.Debugf("Resolved %s tag into %s...", helm.StableVersionTag, helm.HelmRepoStable)
opts.HelmParams.RepoLocation = helm.HelmRepoStable
case helm.LocalVersionTag:
status.Debugf("Resolved %s tag into %s...", helm.LocalVersionTag, helm.LocalChartsPath)
opts.HelmParams.RepoLocation = helm.LocalChartsPath
opts.HelmParams.Version = ""
}

if opts.HelmParams.Version == LatestVersionTag {
if opts.HelmParams.Version == helm.LatestVersionTag {
ver, err := helm.GetLatestVersion(opts.HelmParams.RepoLocation, opts.HelmParams.ChartName)
if err != nil {
return err
}
status.Debugf("Resolved %s tag into %s...", LatestVersionTag, ver)
status.Debugf("Resolved %s tag into %s...", helm.LatestVersionTag, ver)
opts.HelmParams.Version = ver
}

Expand Down
35 changes: 28 additions & 7 deletions internal/cli/migrate/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"strings"

"github.com/xyproto/randomstring"

"github.com/kubeshop/botkube/internal/ptr"
gqlModel "github.com/kubeshop/botkube/internal/remote/graphql"
bkconfig "github.com/kubeshop/botkube/pkg/config"
Expand All @@ -20,23 +22,42 @@ func NewConverter() *Converter {
}

// ConvertActions converts Actions.
func (c *Converter) ConvertActions(actions bkconfig.Actions) []*gqlModel.ActionCreateUpdateInput {
func (c *Converter) ConvertActions(actions bkconfig.Actions, sources map[string]bkconfig.Sources, executors map[string]bkconfig.Executors) []*gqlModel.ActionCreateUpdateInput {
var out []*gqlModel.ActionCreateUpdateInput
for name, act := range actions {
bindings, ok := checkActionBindingExists(act, sources, executors)
if !ok {
continue
}
out = append(out, &gqlModel.ActionCreateUpdateInput{
Name: name,
DisplayName: act.DisplayName,
Enabled: act.Enabled,
Command: act.Command,
Bindings: &gqlModel.ActionCreateUpdateInputBindings{
Sources: act.Bindings.Sources,
Executors: act.Bindings.Executors,
},
Bindings: bindings,
})
}
return out
}

func checkActionBindingExists(act bkconfig.Action, sources map[string]bkconfig.Sources, executors map[string]bkconfig.Executors) (*gqlModel.ActionCreateUpdateInputBindings, bool) {
for _, source := range act.Bindings.Sources {
if _, ok := sources[source]; !ok {
return nil, false
}
}
for _, executor := range act.Bindings.Executors {
if _, ok := executors[executor]; !ok {
return nil, false
}
}

return &gqlModel.ActionCreateUpdateInputBindings{
Sources: act.Bindings.Sources,
Executors: act.Bindings.Executors,
}, true
}

// ConvertAliases converts Aliases.
func (c *Converter) ConvertAliases(aliases bkconfig.Aliases, instanceID string) []*gqlModel.AliasCreateInput {
var out []*gqlModel.AliasCreateInput
Expand Down Expand Up @@ -89,7 +110,7 @@ func (c *Converter) convertExecutors(executors map[string]bkconfig.Executors) ([
Type: gqlModel.PluginTypeExecutor,
Configurations: []*gqlModel.PluginConfigurationInput{
{
Name: cfgName,
Name: fmt.Sprintf("%s_%s", cfgName, randomstring.String(5)),
Configuration: string(rawCfg),
Rbac: c.convertRbac(p.Context),
},
Expand Down Expand Up @@ -120,7 +141,7 @@ func (c *Converter) convertSources(sources map[string]bkconfig.Sources) ([]*gqlM
Type: gqlModel.PluginTypeSource,
Configurations: []*gqlModel.PluginConfigurationInput{
{
Name: cfgName,
Name: fmt.Sprintf("%s_%s", cfgName, randomstring.String(5)),
Configuration: string(rawCfg),
Rbac: c.convertRbac(p.Context),
},
Expand Down
Loading

0 comments on commit fb16ffe

Please sign in to comment.