From 01319e1dc9f5bf7b9ac053e447f4b06a6743dff3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 26 Jun 2014 17:05:21 -0700 Subject: [PATCH] Ui hook --- command/hook_ui.go | 20 ++++++++++++++++++++ commands.go | 11 +++++++---- main.go | 3 +++ terraform/hook.go | 8 ++++---- terraform/hook_mock.go | 8 ++++++-- terraform/terraform.go | 4 ++-- 6 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 command/hook_ui.go diff --git a/command/hook_ui.go b/command/hook_ui.go new file mode 100644 index 000000000..afd599d11 --- /dev/null +++ b/command/hook_ui.go @@ -0,0 +1,20 @@ +package command + +import ( + "fmt" + + "github.com/hashicorp/terraform/terraform" + "github.com/mitchellh/cli" +) + +type UiHook struct { + terraform.NilHook + + Ui cli.Ui +} + +func (h *UiHook) PreRefresh( + id string, s *terraform.ResourceState) (terraform.HookAction, error) { + h.Ui.Output(fmt.Sprintf("Refreshing state for %s (ID: %s)", id, s.ID)) + return terraform.HookActionContinue, nil +} diff --git a/commands.go b/commands.go index 9fddde33c..f290d4658 100644 --- a/commands.go +++ b/commands.go @@ -10,11 +10,14 @@ import ( // Commands is the mapping of all the available Terraform commands. var Commands map[string]cli.CommandFactory +// Ui is the cli.Ui used for communicating to the outside world. +var Ui cli.Ui + const ErrorPrefix = "e:" const OutputPrefix = "o:" func init() { - ui := &cli.PrefixedUi{ + Ui = &cli.PrefixedUi{ AskPrefix: OutputPrefix, OutputPrefix: OutputPrefix, InfoPrefix: OutputPrefix, @@ -26,14 +29,14 @@ func init() { "apply": func() (cli.Command, error) { return &command.ApplyCommand{ TFConfig: &TFConfig, - Ui: ui, + Ui: Ui, }, nil }, "plan": func() (cli.Command, error) { return &command.PlanCommand{ TFConfig: &TFConfig, - Ui: ui, + Ui: Ui, }, nil }, @@ -42,7 +45,7 @@ func init() { Revision: GitCommit, Version: Version, VersionPrerelease: VersionPrerelease, - Ui: ui, + Ui: Ui, }, nil }, } diff --git a/main.go b/main.go index 31c0d5aed..fbe6b9948 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,9 @@ import ( "log" "os" + "github.com/hashicorp/terraform/command" "github.com/hashicorp/terraform/plugin" + "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" "github.com/mitchellh/panicwrap" "github.com/mitchellh/prefixedio" @@ -84,6 +86,7 @@ func wrappedMain() int { defer plugin.CleanupClients() // Initialize the TFConfig settings for the commands... + TFConfig.Hooks = []terraform.Hook{&command.UiHook{Ui: Ui}} TFConfig.Providers = config.ProviderFactories() // Get the command line args. We shortcut "--version" and "-v" to diff --git a/terraform/hook.go b/terraform/hook.go index 05ce9d76a..dc1a16fbd 100644 --- a/terraform/hook.go +++ b/terraform/hook.go @@ -22,10 +22,10 @@ const ( // nothing. Then, override only the functions you want to implement. type Hook interface { // PreRefresh is called before a resource is refreshed. - PreRefresh(*ResourceState) (HookAction, error) + PreRefresh(string, *ResourceState) (HookAction, error) // PostRefresh is called after a resource is refreshed. - PostRefresh(*ResourceState) (HookAction, error) + PostRefresh(string, *ResourceState) (HookAction, error) } // NilHook is a Hook implementation that does nothing. It exists only to @@ -33,10 +33,10 @@ type Hook interface { // and only implement the functions you are interested in. type NilHook struct{} -func (*NilHook) PreRefresh(*ResourceState) (HookAction, error) { +func (*NilHook) PreRefresh(string, *ResourceState) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PostRefresh(*ResourceState) (HookAction, error) { +func (*NilHook) PostRefresh(string, *ResourceState) (HookAction, error) { return HookActionContinue, nil } diff --git a/terraform/hook_mock.go b/terraform/hook_mock.go index ca8140e81..90b1852e9 100644 --- a/terraform/hook_mock.go +++ b/terraform/hook_mock.go @@ -4,24 +4,28 @@ package terraform // It records all of its function calls. type MockHook struct { PostRefreshCalled bool + PostRefreshId string PostRefreshState *ResourceState PostRefreshReturn HookAction PostRefreshError error PreRefreshCalled bool + PreRefreshId string PreRefreshState *ResourceState PreRefreshReturn HookAction PreRefreshError error } -func (h *MockHook) PreRefresh(s *ResourceState) (HookAction, error) { +func (h *MockHook) PreRefresh(n string, s *ResourceState) (HookAction, error) { h.PreRefreshCalled = true + h.PreRefreshId = n h.PreRefreshState = s return h.PreRefreshReturn, h.PreRefreshError } -func (h *MockHook) PostRefresh(s *ResourceState) (HookAction, error) { +func (h *MockHook) PostRefresh(n string, s *ResourceState) (HookAction, error) { h.PostRefreshCalled = true + h.PostRefreshId = n h.PostRefreshState = s return h.PostRefreshReturn, h.PostRefreshError } diff --git a/terraform/terraform.go b/terraform/terraform.go index 6cccbda5e..b3266f59f 100644 --- a/terraform/terraform.go +++ b/terraform/terraform.go @@ -133,7 +133,7 @@ func (t *Terraform) refreshWalkFn(result *State) depgraph.WalkFunc { cb := func(r *Resource) (map[string]string, error) { for _, h := range t.hooks { // TODO: return value - h.PreRefresh(r.State) + h.PreRefresh(r.Id, r.State) } rs, err := r.Provider.Refresh(r.State) @@ -153,7 +153,7 @@ func (t *Terraform) refreshWalkFn(result *State) depgraph.WalkFunc { for _, h := range t.hooks { // TODO: return value - h.PostRefresh(rs) + h.PostRefresh(r.Id, rs) } return nil, nil