Skip to content

Commit

Permalink
Port bug fixes into v1.2 (#1145)
Browse files Browse the repository at this point in the history
* Fix brew release, add windows, use binary format (#1144)

* Add build flags to CLI (#1146)

* Plugins logger respect generic logger settings (#1147)

* Add timestamp annotation on update (#1148)

* Rename `--auto-upgrade` to `--auto-approve` flag for Migration CLI (#1149)

* Unify auto-approve flag for Migration CLI
  • Loading branch information
mszostok authored Jul 17, 2023
1 parent b954115 commit a30c360
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 19 deletions.
11 changes: 8 additions & 3 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ builds:
-X github.com/kubeshop/botkube/cmd/cli/cmd/migrate.DefaultImageTag={{ .Env.IMAGE_TAG }}
-X go.szostok.io/version.version={{.Version}}
-X go.szostok.io/version.buildDate={{.Date}}
- -X go.szostok.io/version.commit={{.FullCommit}}
- -X go.szostok.io/version.commitDate={{.CommitDate}}
-X go.szostok.io/version.name=botkube
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm
Expand Down Expand Up @@ -150,6 +153,8 @@ docker_manifests:

archives:
- id: botkube-cli
format: binary
name_template: "{{ .Binary }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
builds:
- botkube-cli
brews:
Expand All @@ -164,8 +169,8 @@ brews:
token: "{{ .Env.GITHUB_TOKEN }}"
download_strategy: CurlDownloadStrategy
commit_msg_template: "Brew formula update for {{ .ProjectName }} version {{ .Tag }}"
folder: Formula
homepage: "https://botkube.io"
description: "Botkube CLI is a command line tool for managing Botkube instances"
description: "Botkube CLI is a command line tool for managing Botkube resources"
license: "MIT"

test: |
system "#{bin}/botkube version -o=short"
2 changes: 1 addition & 1 deletion cmd/botkube-agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func run(ctx context.Context) error {

collector := plugin.NewCollector(logger)
enabledPluginExecutors, enabledPluginSources := collector.GetAllEnabledAndUsedPlugins(conf)
pluginManager := plugin.NewManager(logger, conf.Plugins, enabledPluginExecutors, enabledPluginSources)
pluginManager := plugin.NewManager(logger, conf.Settings.Log, conf.Plugins, enabledPluginExecutors, enabledPluginSources)

err = pluginManager.Start(ctx)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/cli/cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func NewMigrate() *cobra.Command {
flags.StringVarP(&opts.Namespace, "namespace", "n", "botkube", "Namespace of Botkube pod")
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.BoolVar(&opts.AutoUpgrade, "auto-upgrade", false, "Automatically upgrades Botkube instance without additional prompt")
flags.BoolVarP(&opts.AutoApprove, "auto-approve", "y", false, "Skips interactive approval for upgrading Botkube installation.")
flags.StringVar(&opts.ConfigExporter.Registry, "cfg-exporter-image-registry", "ghcr.io", "Config Exporter job image registry")
flags.StringVar(&opts.ConfigExporter.Repository, "cfg-exporter-image-repo", "kubeshop/botkube-config-exporter", "Config Exporter job image repository")
flags.StringVar(&opts.ConfigExporter.Tag, "cfg-exporter-image-tag", DefaultImageTag, "Config Exporter job image tag")
Expand Down
2 changes: 1 addition & 1 deletion cmd/cli/docs/botkube_migrate.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ botkube migrate [OPTIONS] [flags]
### Options

```
--auto-upgrade Automatically upgrades Botkube instance without additional prompt
-y, --auto-approve Skips interactive approval for upgrading Botkube installation.
--cfg-exporter-image-registry string Config Exporter job image registry (default "ghcr.io")
--cfg-exporter-image-repo string Config Exporter job image repository (default "kubeshop/botkube-config-exporter")
--cfg-exporter-image-tag string Config Exporter job image tag (default "v9.99.9-dev")
Expand Down
12 changes: 12 additions & 0 deletions internal/cli/install/helm/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ import (
"helm.sh/helm/v3/pkg/storage/driver"
"k8s.io/client-go/rest"

"github.com/kubeshop/botkube/internal/cli"
"github.com/kubeshop/botkube/internal/cli/helmx"
"github.com/kubeshop/botkube/internal/cli/install/iox"
"github.com/kubeshop/botkube/internal/cli/printer"
)

const restartAnnotationFmt = "extraAnnotations.cli\\.botkube\\.io\\/restart\\-timestamp=\"%d\""

// Run provides single function signature both for install and upgrade.
type Run func(ctx context.Context, relName string, chart *chart.Chart, vals map[string]any) (*release.Release, error)

Expand Down Expand Up @@ -77,6 +80,15 @@ func (c *Helm) Install(ctx context.Context, status *printer.StatusPrinter, opts
return nil, errors.New("upgrade aborted")
}
}
restartAnnotation := fmt.Sprintf(restartAnnotationFmt, time.Now().Unix())
if cli.VerboseMode.IsEnabled() {
status.Step("Appending %q Pod annotation to enforce Pod restart", restartAnnotation)
} else {
status.Step("Appending Pod annotation to enforce Pod restart")
}
opts.Values.Values = append(opts.Values.Values, restartAnnotation)
status.End(true)

runFn = c.upgradeAction(opts)
case err == driver.ErrReleaseNotFound:
runFn = c.installAction(opts)
Expand Down
21 changes: 20 additions & 1 deletion internal/cli/install/logs/json_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"sort"
"strings"

charmlog "github.com/charmbracelet/log"
"golang.org/x/exp/maps"
Expand All @@ -23,7 +24,7 @@ func (j *JSONParser) ParseLineIntoCharm(line string) ([]any, charmlog.Level) {

var fields []any

lvl := charmlog.ParseLevel(fmt.Sprint(result["level"]))
lvl := parseLevel(fmt.Sprint(result["level"]))
fields = append(fields, charmlog.LevelKey, lvl)
fields = append(fields, charmlog.MessageKey, result["msg"])

Expand Down Expand Up @@ -52,3 +53,21 @@ func (*JSONParser) parseLine(line string) map[string]any {
}
return out
}

// parseLevel takes a string level and returns the charm log level constant.
func parseLevel(lvl string) charmlog.Level {
switch strings.ToLower(lvl) {
case "panic", "fatal":
return charmlog.FatalLevel
case "error", "err":
return charmlog.ErrorLevel
case "warn", "warning":
return charmlog.WarnLevel
case "info":
return charmlog.InfoLevel
case "debug", "trace":
return charmlog.DebugLevel
default:
return charmlog.InfoLevel
}
}
2 changes: 1 addition & 1 deletion internal/cli/migrate/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ func errStateMessage(dashboardURL, instanceID string) string {
}

func shouldUpgradeInstallation(opts Options) (bool, error) {
if opts.AutoUpgrade {
if opts.AutoApprove {
return true, nil
}

Expand Down
2 changes: 1 addition & 1 deletion internal/cli/migrate/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Options struct {
Label string
SkipConnect bool
SkipOpenBrowser bool
AutoUpgrade bool
AutoApprove bool
ConfigExporter ConfigExporterOptions
}

Expand Down
3 changes: 2 additions & 1 deletion internal/plugin/index_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/xeipuuv/gojsonschema"

"github.com/kubeshop/botkube/pkg/api"
"github.com/kubeshop/botkube/pkg/config"
"github.com/kubeshop/botkube/pkg/multierror"
)

Expand Down Expand Up @@ -170,7 +171,7 @@ func (i *IndexBuilder) getPluginMetadata(dir string, bins []pluginBinariesIndex)
bins := map[string]string{
item.Type.String(): filepath.Join(dir, item.BinaryPath),
}
clients, err := createGRPCClients[metadataGetter](i.log, bins, item.Type)
clients, err := createGRPCClients[metadataGetter](i.log, config.Logger{}, bins, item.Type)
if err != nil {
return nil, fmt.Errorf("while creating gRPC client: %w", err)
}
Expand Down
6 changes: 4 additions & 2 deletions internal/plugin/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ var specialCharsPattern = regexp.MustCompile(`(?i:[^A-Z0-9_])`)
// - hashicorp client logger always has the configured log level
// - binary standard output is logged only if debug level is set, otherwise it is discarded
// - binary standard error is logged always on error level
func NewPluginLoggers(bkLogger logrus.FieldLogger, pluginKey string, pluginType Type) (hclog.Logger, io.Writer, io.Writer) {
func NewPluginLoggers(bkLogger logrus.FieldLogger, logConfig config.Logger, pluginKey string, pluginType Type) (hclog.Logger, io.Writer, io.Writer) {
pluginLogLevel := getPluginLogLevel(bkLogger, pluginKey, pluginType)

cfg := config.Logger{
Level: pluginLogLevel.String(),
Level: pluginLogLevel.String(),
DisableColors: logConfig.DisableColors,
Formatter: logConfig.Formatter,
}
log := loggerx.New(cfg).WithField("plugin", pluginKey)

Expand Down
12 changes: 7 additions & 5 deletions internal/plugin/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ var pluginMap = map[string]plugin.Plugin{
type Manager struct {
isStarted atomic.Bool
log logrus.FieldLogger
logConfig config.Logger
cfg config.PluginManagement
httpClient *http.Client

Expand All @@ -58,7 +59,7 @@ type Manager struct {
}

// NewManager returns a new Manager instance.
func NewManager(logger logrus.FieldLogger, cfg config.PluginManagement, executors, sources []string) *Manager {
func NewManager(logger logrus.FieldLogger, logCfg config.Logger, cfg config.PluginManagement, executors, sources []string) *Manager {
return &Manager{
cfg: cfg,
httpClient: httpx.NewHTTPClient(),
Expand All @@ -67,6 +68,7 @@ func NewManager(logger logrus.FieldLogger, cfg config.PluginManagement, executor
sourcesToEnable: sources,
sourcesStore: newStore[source.Source](),
log: logger.WithField("component", "Plugin Manager"),
logConfig: logCfg, // used when we create on-demand loggers for plugins
}
}

Expand Down Expand Up @@ -106,7 +108,7 @@ func (m *Manager) start(ctx context.Context, forceUpdate bool) error {
return err
}

executorClients, err := createGRPCClients[executor.Executor](m.log, executorPlugins, TypeExecutor)
executorClients, err := createGRPCClients[executor.Executor](m.log, m.logConfig, executorPlugins, TypeExecutor)
if err != nil {
return fmt.Errorf("while creating executor plugins: %w", err)
}
Expand All @@ -116,7 +118,7 @@ func (m *Manager) start(ctx context.Context, forceUpdate bool) error {
if err != nil {
return err
}
sourcesClients, err := createGRPCClients[source.Source](m.log, sourcesPlugins, TypeSource)
sourcesClients, err := createGRPCClients[source.Source](m.log, m.logConfig, sourcesPlugins, TypeSource)
if err != nil {
return fmt.Errorf("while creating source plugins: %w", err)
}
Expand Down Expand Up @@ -324,11 +326,11 @@ func (m *Manager) fetchIndex(ctx context.Context, path, url string) error {
return nil
}

func createGRPCClients[C any](logger logrus.FieldLogger, bins map[string]string, pluginType Type) (map[string]enabledPlugins[C], error) {
func createGRPCClients[C any](logger logrus.FieldLogger, logConfig config.Logger, bins map[string]string, pluginType Type) (map[string]enabledPlugins[C], error) {
out := map[string]enabledPlugins[C]{}

for key, path := range bins {
pluginLogger, stdoutLogger, stderrLogger := NewPluginLoggers(logger, key, pluginType)
pluginLogger, stdoutLogger, stderrLogger := NewPluginLoggers(logger, logConfig, key, pluginType)

cli := plugin.NewClient(&plugin.ClientConfig{
Plugins: pluginMap,
Expand Down
2 changes: 1 addition & 1 deletion internal/plugin/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func TestCollectEnabledRepositories(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
// given
manager := NewManager(loggerx.NewNoop(), config.PluginManagement{
manager := NewManager(loggerx.NewNoop(), config.Logger{}, config.PluginManagement{
Repositories: tc.definedRepositories,
}, tc.enabledExecutors, tc.enabledSources)

Expand Down
2 changes: 1 addition & 1 deletion test/e2e/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func TestBotkubeMigration(t *testing.T) {

t.Run("Migrate Discord Botkube to Botkube Cloud", func(t *testing.T) {
cmd := exec.Command(appCfg.BotkubeBinaryPath, "migrate",
"--auto-upgrade",
"--auto-approve",
"--skip-open-browser",
"--verbose",
fmt.Sprintf("--token=%s", token),
Expand Down

0 comments on commit a30c360

Please sign in to comment.