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
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.TFConfig.Hooks = append(c.TFConfig.Hooks, &UiHook{Ui: c.Ui})
|
||||||
tf, err := terraform.New(c.TFConfig)
|
tf, err := terraform.New(c.TFConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf("Error initializing Terraform: %s", err))
|
c.Ui.Error(fmt.Sprintf("Error initializing Terraform: %s", err))
|
||||||
|
|
3
main.go
3
main.go
|
@ -7,9 +7,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/command"
|
|
||||||
"github.com/hashicorp/terraform/plugin"
|
"github.com/hashicorp/terraform/plugin"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
"github.com/mitchellh/panicwrap"
|
"github.com/mitchellh/panicwrap"
|
||||||
"github.com/mitchellh/prefixedio"
|
"github.com/mitchellh/prefixedio"
|
||||||
|
@ -86,7 +84,6 @@ func wrappedMain() int {
|
||||||
defer plugin.CleanupClients()
|
defer plugin.CleanupClients()
|
||||||
|
|
||||||
// Initialize the TFConfig settings for the commands...
|
// Initialize the TFConfig settings for the commands...
|
||||||
TFConfig.Hooks = []terraform.Hook{&command.UiHook{Ui: Ui}}
|
|
||||||
TFConfig.Providers = config.ProviderFactories()
|
TFConfig.Providers = config.ProviderFactories()
|
||||||
|
|
||||||
// Get the command line args. We shortcut "--version" and "-v" to
|
// 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
|
// NilHook into your struct, which implements all of the interface but does
|
||||||
// nothing. Then, override only the functions you want to implement.
|
// nothing. Then, override only the functions you want to implement.
|
||||||
type Hook interface {
|
type Hook interface {
|
||||||
// PreRefresh is called before a resource is refreshed.
|
// PreDiff and PostDiff are called before and after a single resource
|
||||||
PreRefresh(string, *ResourceState) (HookAction, error)
|
// 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)
|
PostRefresh(string, *ResourceState) (HookAction, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +37,14 @@ type Hook interface {
|
||||||
// and only implement the functions you are interested in.
|
// and only implement the functions you are interested in.
|
||||||
type NilHook struct{}
|
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) {
|
func (*NilHook) PreRefresh(string, *ResourceState) (HookAction, error) {
|
||||||
return HookActionContinue, nil
|
return HookActionContinue, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,18 @@ package terraform
|
||||||
// MockHook is an implementation of Hook that can be used for tests.
|
// MockHook is an implementation of Hook that can be used for tests.
|
||||||
// It records all of its function calls.
|
// It records all of its function calls.
|
||||||
type MockHook struct {
|
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
|
PostRefreshCalled bool
|
||||||
PostRefreshId string
|
PostRefreshId string
|
||||||
PostRefreshState *ResourceState
|
PostRefreshState *ResourceState
|
||||||
|
@ -16,6 +28,20 @@ type MockHook struct {
|
||||||
PreRefreshError error
|
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) {
|
func (h *MockHook) PreRefresh(n string, s *ResourceState) (HookAction, error) {
|
||||||
h.PreRefreshCalled = true
|
h.PreRefreshCalled = true
|
||||||
h.PreRefreshId = n
|
h.PreRefreshId = n
|
||||||
|
|
|
@ -243,6 +243,11 @@ func (t *Terraform) planWalkFn(
|
||||||
cb := func(r *Resource) (map[string]string, error) {
|
cb := func(r *Resource) (map[string]string, error) {
|
||||||
var diff *ResourceDiff
|
var diff *ResourceDiff
|
||||||
|
|
||||||
|
for _, h := range t.hooks {
|
||||||
|
// TODO: return value
|
||||||
|
h.PreDiff(r.Id, r.State)
|
||||||
|
}
|
||||||
|
|
||||||
if r.Config == nil {
|
if r.Config == nil {
|
||||||
log.Printf("[DEBUG] %s: Orphan, marking for destroy", r.Id)
|
log.Printf("[DEBUG] %s: Orphan, marking for destroy", r.Id)
|
||||||
|
|
||||||
|
@ -265,6 +270,11 @@ func (t *Terraform) planWalkFn(
|
||||||
}
|
}
|
||||||
l.Unlock()
|
l.Unlock()
|
||||||
|
|
||||||
|
for _, h := range t.hooks {
|
||||||
|
// TODO: return value
|
||||||
|
h.PostDiff(r.Id, diff)
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the new state and update variables
|
// Determine the new state and update variables
|
||||||
vars := make(map[string]string)
|
vars := make(map[string]string)
|
||||||
if !diff.Empty() {
|
if !diff.Empty() {
|
||||||
|
@ -311,7 +321,7 @@ func (t *Terraform) genericWalkFn(
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, p := range m.Providers {
|
for k, p := range m.Providers {
|
||||||
log.Printf("Configuring provider: %s", k)
|
log.Printf("[INFO] Configuring provider: %s", k)
|
||||||
err := p.Configure(rc)
|
err := p.Configure(rc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -345,7 +355,7 @@ func (t *Terraform) genericWalkFn(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the callack
|
// Call the callack
|
||||||
log.Printf("Walking: %s", rn.Resource.Id)
|
log.Printf("[INFO] Walking: %s", rn.Resource.Id)
|
||||||
newVars, err := cb(rn.Resource)
|
newVars, err := cb(rn.Resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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) {
|
func TestTerraformPlan_orphan(t *testing.T) {
|
||||||
c := testConfig(t, "plan-orphan")
|
c := testConfig(t, "plan-orphan")
|
||||||
tf := testTerraform2(t, nil)
|
tf := testTerraform2(t, nil)
|
||||||
|
@ -462,11 +480,13 @@ func testProviderMock(p ResourceProvider) *MockResourceProvider {
|
||||||
|
|
||||||
func testTerraform2(t *testing.T, c *Config) *Terraform {
|
func testTerraform2(t *testing.T, c *Config) *Terraform {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
c = &Config{
|
c = new(Config)
|
||||||
Providers: map[string]ResourceProviderFactory{
|
}
|
||||||
"aws": testProviderFunc("aws", []string{"aws_instance"}),
|
|
||||||
"do": testProviderFunc("do", []string{"do_droplet"}),
|
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