command/apply: show add/remove/change count for apply
This commit is contained in:
parent
3077800252
commit
ba4435f99c
|
@ -50,6 +50,10 @@ func (c *ApplyCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare the extra hooks to count resources
|
||||||
|
countHook := new(CountHook)
|
||||||
|
c.Meta.extraHooks = []terraform.Hook{countHook}
|
||||||
|
|
||||||
// If we don't specify an output path, default to out normal state
|
// If we don't specify an output path, default to out normal state
|
||||||
// path.
|
// path.
|
||||||
if stateOutPath == "" {
|
if stateOutPath == "" {
|
||||||
|
@ -124,13 +128,21 @@ func (c *ApplyCommand) Run(args []string) int {
|
||||||
|
|
||||||
c.Ui.Output(c.Colorize().Color(fmt.Sprintf(
|
c.Ui.Output(c.Colorize().Color(fmt.Sprintf(
|
||||||
"[reset][bold][green]\n"+
|
"[reset][bold][green]\n"+
|
||||||
"Apply succeeded! Infrastructure created and/or updated.\n"+
|
"Apply complete! Resources: %d added, %d changed, %d destroyed.",
|
||||||
"The state of your infrastructure has been saved to the path\n"+
|
countHook.Added,
|
||||||
"below. This state is required to modify and destroy your\n"+
|
countHook.Changed,
|
||||||
"infrastructure, so keep it safe. To inspect the complete state\n"+
|
countHook.Removed)))
|
||||||
"use the `terraform show` command.\n\n"+
|
|
||||||
"State path: %s",
|
if countHook.Added > 0 || countHook.Changed > 0 {
|
||||||
stateOutPath)))
|
c.Ui.Output(c.Colorize().Color(fmt.Sprintf(
|
||||||
|
"[reset]\n"+
|
||||||
|
"The state of your infrastructure has been saved to the path\n"+
|
||||||
|
"below. This state is required to modify and destroy your\n"+
|
||||||
|
"infrastructure, so keep it safe. To inspect the complete state\n"+
|
||||||
|
"use the `terraform show` command.\n\n"+
|
||||||
|
"State path: %s",
|
||||||
|
stateOutPath)))
|
||||||
|
}
|
||||||
|
|
||||||
// If we have outputs, then output those at the end.
|
// If we have outputs, then output those at the end.
|
||||||
if len(state.Outputs) > 0 {
|
if len(state.Outputs) > 0 {
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CountHook is a hook that counts the number of resources
|
||||||
|
// added, removed, changed during the course of an apply.
|
||||||
|
type CountHook struct {
|
||||||
|
Added int
|
||||||
|
Changed int
|
||||||
|
Removed int
|
||||||
|
|
||||||
|
pending map[string]countHookAction
|
||||||
|
|
||||||
|
sync.Mutex
|
||||||
|
terraform.NilHook
|
||||||
|
}
|
||||||
|
|
||||||
|
type countHookAction byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
countHookActionAdd countHookAction = iota
|
||||||
|
countHookActionChange
|
||||||
|
countHookActionRemove
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *CountHook) Reset() {
|
||||||
|
h.Lock()
|
||||||
|
defer h.Unlock()
|
||||||
|
|
||||||
|
h.pending = nil
|
||||||
|
h.Added = 0
|
||||||
|
h.Changed = 0
|
||||||
|
h.Removed = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *CountHook) PreApply(
|
||||||
|
id string,
|
||||||
|
s *terraform.ResourceState,
|
||||||
|
d *terraform.ResourceDiff) (terraform.HookAction, error) {
|
||||||
|
h.Lock()
|
||||||
|
defer h.Unlock()
|
||||||
|
|
||||||
|
if h.pending == nil {
|
||||||
|
h.pending = make(map[string]countHookAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
action := countHookActionChange
|
||||||
|
if d.Destroy {
|
||||||
|
action = countHookActionRemove
|
||||||
|
} else if s.ID == "" {
|
||||||
|
action = countHookActionAdd
|
||||||
|
}
|
||||||
|
|
||||||
|
h.pending[id] = action
|
||||||
|
|
||||||
|
return terraform.HookActionContinue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *CountHook) PostApply(
|
||||||
|
id string,
|
||||||
|
s *terraform.ResourceState) (terraform.HookAction, error) {
|
||||||
|
h.Lock()
|
||||||
|
defer h.Unlock()
|
||||||
|
|
||||||
|
if h.pending != nil {
|
||||||
|
if a, ok := h.pending[id]; ok {
|
||||||
|
switch a {
|
||||||
|
case countHookActionAdd:
|
||||||
|
h.Added += 1
|
||||||
|
case countHookActionChange:
|
||||||
|
h.Changed += 1
|
||||||
|
case countHookActionRemove:
|
||||||
|
h.Removed += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return terraform.HookActionContinue, nil
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCountHook_impl(t *testing.T) {
|
||||||
|
var _ terraform.Hook = new(CountHook)
|
||||||
|
}
|
|
@ -16,6 +16,9 @@ type Meta struct {
|
||||||
ContextOpts *terraform.ContextOpts
|
ContextOpts *terraform.ContextOpts
|
||||||
Ui cli.Ui
|
Ui cli.Ui
|
||||||
|
|
||||||
|
// This can be set by the command itself to provide extra hooks.
|
||||||
|
extraHooks []terraform.Hook
|
||||||
|
|
||||||
color bool
|
color bool
|
||||||
oldUi cli.Ui
|
oldUi cli.Ui
|
||||||
}
|
}
|
||||||
|
@ -99,9 +102,13 @@ func (m *Meta) Context(path, statePath string, doPlan bool) (*terraform.Context,
|
||||||
// context with the settings from this Meta.
|
// context with the settings from this Meta.
|
||||||
func (m *Meta) contextOpts() *terraform.ContextOpts {
|
func (m *Meta) contextOpts() *terraform.ContextOpts {
|
||||||
var opts terraform.ContextOpts = *m.ContextOpts
|
var opts terraform.ContextOpts = *m.ContextOpts
|
||||||
opts.Hooks = make([]terraform.Hook, len(m.ContextOpts.Hooks)+1)
|
opts.Hooks = make(
|
||||||
|
[]terraform.Hook,
|
||||||
|
len(m.ContextOpts.Hooks)+len(m.extraHooks)+1)
|
||||||
opts.Hooks[0] = m.uiHook()
|
opts.Hooks[0] = m.uiHook()
|
||||||
copy(opts.Hooks[1:], m.ContextOpts.Hooks)
|
copy(opts.Hooks[1:], m.ContextOpts.Hooks)
|
||||||
|
copy(opts.Hooks[len(m.ContextOpts.Hooks)+1:], m.extraHooks)
|
||||||
|
println(fmt.Sprintf("%#v", opts.Hooks))
|
||||||
return &opts
|
return &opts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue