terraform: diff hooks
This commit is contained in:
parent
01319e1dc9
commit
ae6b85e11b
|
@ -62,6 +62,7 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
c.TFConfig.Hooks = append(c.TFConfig.Hooks, &UiHook{Ui: c.Ui})
|
||||
tf, err := terraform.New(c.TFConfig)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error initializing Terraform: %s", err))
|
||||
|
|
3
main.go
3
main.go
|
@ -7,9 +7,7 @@ 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"
|
||||
|
@ -86,7 +84,6 @@ 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
|
||||
|
|
|
@ -21,10 +21,14 @@ const (
|
|||
// NilHook into your struct, which implements all of the interface but does
|
||||
// nothing. Then, override only the functions you want to implement.
|
||||
type Hook interface {
|
||||
// PreRefresh is called before a resource is refreshed.
|
||||
PreRefresh(string, *ResourceState) (HookAction, error)
|
||||
// PreDiff and PostDiff are called before and after a single resource
|
||||
// resource is diffed.
|
||||
PreDiff(string, *ResourceState) (HookAction, error)
|
||||
PostDiff(string, *ResourceDiff) (HookAction, error)
|
||||
|
||||
// PostRefresh is called after a resource is refreshed.
|
||||
// PreRefresh and PostRefresh are called before and after a single
|
||||
// resource state is refreshed, respectively.
|
||||
PreRefresh(string, *ResourceState) (HookAction, error)
|
||||
PostRefresh(string, *ResourceState) (HookAction, error)
|
||||
}
|
||||
|
||||
|
@ -33,6 +37,14 @@ type Hook interface {
|
|||
// and only implement the functions you are interested in.
|
||||
type NilHook struct{}
|
||||
|
||||
func (*NilHook) PreDiff(string, *ResourceState) (HookAction, error) {
|
||||
return HookActionContinue, nil
|
||||
}
|
||||
|
||||
func (*NilHook) PostDiff(string, *ResourceDiff) (HookAction, error) {
|
||||
return HookActionContinue, nil
|
||||
}
|
||||
|
||||
func (*NilHook) PreRefresh(string, *ResourceState) (HookAction, error) {
|
||||
return HookActionContinue, nil
|
||||
}
|
||||
|
|
|
@ -3,6 +3,18 @@ package terraform
|
|||
// MockHook is an implementation of Hook that can be used for tests.
|
||||
// It records all of its function calls.
|
||||
type MockHook struct {
|
||||
PreDiffCalled bool
|
||||
PreDiffId string
|
||||
PreDiffState *ResourceState
|
||||
PreDiffReturn HookAction
|
||||
PreDiffError error
|
||||
|
||||
PostDiffCalled bool
|
||||
PostDiffId string
|
||||
PostDiffDiff *ResourceDiff
|
||||
PostDiffReturn HookAction
|
||||
PostDiffError error
|
||||
|
||||
PostRefreshCalled bool
|
||||
PostRefreshId string
|
||||
PostRefreshState *ResourceState
|
||||
|
@ -16,6 +28,20 @@ type MockHook struct {
|
|||
PreRefreshError error
|
||||
}
|
||||
|
||||
func (h *MockHook) PreDiff(n string, s *ResourceState) (HookAction, error) {
|
||||
h.PreDiffCalled = true
|
||||
h.PreDiffId = n
|
||||
h.PreDiffState = s
|
||||
return h.PreDiffReturn, h.PreDiffError
|
||||
}
|
||||
|
||||
func (h *MockHook) PostDiff(n string, d *ResourceDiff) (HookAction, error) {
|
||||
h.PostDiffCalled = true
|
||||
h.PostDiffId = n
|
||||
h.PostDiffDiff = d
|
||||
return h.PostDiffReturn, h.PostDiffError
|
||||
}
|
||||
|
||||
func (h *MockHook) PreRefresh(n string, s *ResourceState) (HookAction, error) {
|
||||
h.PreRefreshCalled = true
|
||||
h.PreRefreshId = n
|
||||
|
|
|
@ -243,6 +243,11 @@ func (t *Terraform) planWalkFn(
|
|||
cb := func(r *Resource) (map[string]string, error) {
|
||||
var diff *ResourceDiff
|
||||
|
||||
for _, h := range t.hooks {
|
||||
// TODO: return value
|
||||
h.PreDiff(r.Id, r.State)
|
||||
}
|
||||
|
||||
if r.Config == nil {
|
||||
log.Printf("[DEBUG] %s: Orphan, marking for destroy", r.Id)
|
||||
|
||||
|
@ -265,6 +270,11 @@ func (t *Terraform) planWalkFn(
|
|||
}
|
||||
l.Unlock()
|
||||
|
||||
for _, h := range t.hooks {
|
||||
// TODO: return value
|
||||
h.PostDiff(r.Id, diff)
|
||||
}
|
||||
|
||||
// Determine the new state and update variables
|
||||
vars := make(map[string]string)
|
||||
if !diff.Empty() {
|
||||
|
@ -311,7 +321,7 @@ func (t *Terraform) genericWalkFn(
|
|||
}
|
||||
|
||||
for k, p := range m.Providers {
|
||||
log.Printf("Configuring provider: %s", k)
|
||||
log.Printf("[INFO] Configuring provider: %s", k)
|
||||
err := p.Configure(rc)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -345,7 +355,7 @@ func (t *Terraform) genericWalkFn(
|
|||
}
|
||||
|
||||
// Call the callack
|
||||
log.Printf("Walking: %s", rn.Resource.Id)
|
||||
log.Printf("[INFO] Walking: %s", rn.Resource.Id)
|
||||
newVars, err := cb(rn.Resource)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -161,6 +161,24 @@ func TestTerraformPlan_computed(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTerraformPlan_hook(t *testing.T) {
|
||||
c := testConfig(t, "plan-good")
|
||||
h := new(MockHook)
|
||||
tf := testTerraform2(t, &Config{
|
||||
Hooks: []Hook{h},
|
||||
})
|
||||
|
||||
if _, err := tf.Plan(c, nil, nil); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if !h.PreDiffCalled {
|
||||
t.Fatal("should be called")
|
||||
}
|
||||
if !h.PostDiffCalled {
|
||||
t.Fatal("should be called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTerraformPlan_orphan(t *testing.T) {
|
||||
c := testConfig(t, "plan-orphan")
|
||||
tf := testTerraform2(t, nil)
|
||||
|
@ -462,11 +480,13 @@ func testProviderMock(p ResourceProvider) *MockResourceProvider {
|
|||
|
||||
func testTerraform2(t *testing.T, c *Config) *Terraform {
|
||||
if c == nil {
|
||||
c = &Config{
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"aws": testProviderFunc("aws", []string{"aws_instance"}),
|
||||
"do": testProviderFunc("do", []string{"do_droplet"}),
|
||||
},
|
||||
c = new(Config)
|
||||
}
|
||||
|
||||
if c.Providers == nil {
|
||||
c.Providers = map[string]ResourceProviderFactory{
|
||||
"aws": testProviderFunc("aws", []string{"aws_instance"}),
|
||||
"do": testProviderFunc("do", []string{"do_droplet"}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue