diff --git a/README.md b/README.md index e533d23c..08c4f986 100644 --- a/README.md +++ b/README.md @@ -829,9 +829,10 @@ A Helmfile hook is a per-release extension point that is composed of: - `events` - `command` - `args` +- `showlogs` Helmfile triggers various `events` while it is running. -Once `events` are triggered, associated `hooks` are executed, by running the `command` with `args`. +Once `events` are triggered, associated `hooks` are executed, by running the `command` with `args`. The standard output of the `command` will be displayed if `showlogs` is set and it's value is `true`. Currently supported `events` are: @@ -857,6 +858,7 @@ releases: # *snip* hooks: - events: ["prepare", "cleanup"] + showlogs: true command: "echo" args: ["{{`{{.Environment.Name}}`}}", "{{`{{.Release.Name}}`}}", "{{`{{.HelmfileCommand}}`}}\ "] diff --git a/pkg/event/bus.go b/pkg/event/bus.go index aa6fe02e..398d3d18 100644 --- a/pkg/event/bus.go +++ b/pkg/event/bus.go @@ -2,18 +2,21 @@ package event import ( "fmt" + "os" + "strings" + "github.com/roboll/helmfile/pkg/environment" "github.com/roboll/helmfile/pkg/helmexec" "github.com/roboll/helmfile/pkg/tmpl" "go.uber.org/zap" - "os" ) type Hook struct { - Name string `yaml:"name"` - Events []string `yaml:"events"` - Command string `yaml:"command"` - Args []string `yaml:"args"` + Name string `yaml:"name"` + Events []string `yaml:"events"` + Command string `yaml:"command"` + Args []string `yaml:"args"` + ShowLogs bool `yaml:"showlogs"` } type event struct { @@ -90,6 +93,10 @@ func (bus *Bus) Trigger(evt string, context map[string]interface{}) (bool, error bytes, err := bus.Runner.Execute(command, args, map[string]string{}) bus.Logger.Debugf("hook[%s]: %s\n", name, string(bytes)) + if hook.ShowLogs { + prefix := fmt.Sprintf("\nhook[%s] logs | ", evt) + bus.Logger.Infow(prefix + strings.ReplaceAll(string(bytes), "\n", prefix)) + } if err != nil { return false, fmt.Errorf("hook[%s]: command `%s` failed: %v", name, command, err) diff --git a/pkg/event/bus_test.go b/pkg/event/bus_test.go index a852d51c..6dfaf2d0 100644 --- a/pkg/event/bus_test.go +++ b/pkg/event/bus_test.go @@ -2,10 +2,13 @@ package event import ( "fmt" - "github.com/roboll/helmfile/pkg/environment" - "github.com/roboll/helmfile/pkg/helmexec" "os" "testing" + + "github.com/roboll/helmfile/pkg/environment" + "github.com/roboll/helmfile/pkg/helmexec" + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" ) var logger = helmexec.NewLogger(os.Stdout, "warn") @@ -35,14 +38,21 @@ func TestTrigger(t *testing.T) { }{ { "okhook1", - &Hook{"okhook1", []string{"foo"}, "ok", []string{}}, + &Hook{"okhook1", []string{"foo"}, "ok", []string{}, true}, + "foo", + true, + "", + }, + { + "okhooké", + &Hook{"okhook2", []string{"foo"}, "ok", []string{}, false}, "foo", true, "", }, { "missinghook1", - &Hook{"okhook1", []string{"foo"}, "ok", []string{}}, + &Hook{"okhook1", []string{"foo"}, "ok", []string{}, false}, "bar", false, "", @@ -56,14 +66,14 @@ func TestTrigger(t *testing.T) { }, { "nghook1", - &Hook{"nghook1", []string{"foo"}, "ng", []string{}}, + &Hook{"nghook1", []string{"foo"}, "ng", []string{}, false}, "foo", false, "hook[nghook1]: command `ng` failed: cmd failed due to invalid cmd: ng", }, { "nghook2", - &Hook{"nghook2", []string{"foo"}, "ok", []string{"ng"}}, + &Hook{"nghook2", []string{"foo"}, "ok", []string{"ng"}, false}, "foo", false, "hook[nghook2]: command `ok` failed: cmd failed due to invalid arg: ng", @@ -77,13 +87,15 @@ func TestTrigger(t *testing.T) { if c.hook != nil { hooks = append(hooks, *c.hook) } + observer, observedLogs := observer.New(zap.InfoLevel) + zeLogger := zap.New(observer).Sugar() bus := &Bus{ Hooks: hooks, StateFilePath: "path/to/helmfile.yaml", BasePath: "path/to", Namespace: "myns", Env: environment.Environment{Name: "prod"}, - Logger: logger, + Logger: zeLogger, ReadFile: readFile, } @@ -109,5 +121,8 @@ func TestTrigger(t *testing.T) { t.Errorf("unexpected error for case \"%s\": %v", c.name, err) } } + if observedLogs.Len() != 0 && !hooks[0].ShowLogs { + t.Errorf("unexpected error for case \"%s\": Logs should not be created : %v", c.name, observedLogs.All()) + } } }