Merge pull request #27512 from hashicorp/jbardin/output-plans
Create and Delete actions for output plans
This commit is contained in:
commit
68b65cc98a
|
@ -6677,3 +6677,58 @@ func TestContext2Plan_variableCustomValidationsSensitive(t *testing.T) {
|
||||||
t.Fatalf("wrong error:\ngot: %s\nwant: message containing %q", got, want)
|
t.Fatalf("wrong error:\ngot: %s\nwant: message containing %q", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContext2Plan_nullOutputNoOp(t *testing.T) {
|
||||||
|
// this should always plan a NoOp change for the output
|
||||||
|
m := testModuleInline(t, map[string]string{
|
||||||
|
"main.tf": `
|
||||||
|
output "planned" {
|
||||||
|
value = false ? 1 : null
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
State: states.BuildState(func(s *states.SyncState) {
|
||||||
|
r := s.Module(addrs.RootModuleInstance)
|
||||||
|
r.SetOutputValue("planned", cty.NullVal(cty.DynamicPseudoType), false)
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
plan, diags := ctx.Plan()
|
||||||
|
if diags.HasErrors() {
|
||||||
|
t.Fatal(diags.Err())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range plan.Changes.Outputs {
|
||||||
|
if c.Action != plans.NoOp {
|
||||||
|
t.Fatalf("expected no changes, got %s for %q", c.Action, c.Addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Plan_createOutput(t *testing.T) {
|
||||||
|
// this should always plan a NoOp change for the output
|
||||||
|
m := testModuleInline(t, map[string]string{
|
||||||
|
"main.tf": `
|
||||||
|
output "planned" {
|
||||||
|
value = 1
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
State: states.NewState(),
|
||||||
|
})
|
||||||
|
plan, diags := ctx.Plan()
|
||||||
|
if diags.HasErrors() {
|
||||||
|
t.Fatal(diags.Err())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range plan.Changes.Outputs {
|
||||||
|
if c.Action != plans.Create {
|
||||||
|
t.Fatalf("expected Create change, got %s for %q", c.Action, c.Addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -432,12 +432,17 @@ func (n *NodeApplyableOutput) setValue(state *states.SyncState, changes *plans.C
|
||||||
// the diff
|
// the diff
|
||||||
sensitiveBefore := false
|
sensitiveBefore := false
|
||||||
before := cty.NullVal(cty.DynamicPseudoType)
|
before := cty.NullVal(cty.DynamicPseudoType)
|
||||||
|
|
||||||
|
// is this output new to our state?
|
||||||
|
newOutput := true
|
||||||
|
|
||||||
mod := state.Module(n.Addr.Module)
|
mod := state.Module(n.Addr.Module)
|
||||||
if n.Addr.Module.IsRoot() && mod != nil {
|
if n.Addr.Module.IsRoot() && mod != nil {
|
||||||
for name, o := range mod.OutputValues {
|
for name, o := range mod.OutputValues {
|
||||||
if name == n.Addr.OutputValue.Name {
|
if name == n.Addr.OutputValue.Name {
|
||||||
before = o.Value
|
before = o.Value
|
||||||
sensitiveBefore = o.Sensitive
|
sensitiveBefore = o.Sensitive
|
||||||
|
newOutput = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,12 +456,15 @@ func (n *NodeApplyableOutput) setValue(state *states.SyncState, changes *plans.C
|
||||||
// strip any marks here just to be sure we don't panic on the True comparison
|
// strip any marks here just to be sure we don't panic on the True comparison
|
||||||
val, _ = val.UnmarkDeep()
|
val, _ = val.UnmarkDeep()
|
||||||
|
|
||||||
var action plans.Action
|
action := plans.Update
|
||||||
switch {
|
switch {
|
||||||
case val.IsNull():
|
case val.IsNull() && before.IsNull():
|
||||||
action = plans.Delete
|
// This is separate from the NoOp case below, since we can ignore
|
||||||
|
// sensitivity here when there are only null values.
|
||||||
|
action = plans.NoOp
|
||||||
|
|
||||||
case before.IsNull():
|
case newOutput:
|
||||||
|
// This output was just added to the configuration
|
||||||
action = plans.Create
|
action = plans.Create
|
||||||
|
|
||||||
case val.IsWhollyKnown() &&
|
case val.IsWhollyKnown() &&
|
||||||
|
@ -467,9 +475,6 @@ func (n *NodeApplyableOutput) setValue(state *states.SyncState, changes *plans.C
|
||||||
// only one we can act on, and the state will have been loaded
|
// only one we can act on, and the state will have been loaded
|
||||||
// without any marks to consider.
|
// without any marks to consider.
|
||||||
action = plans.NoOp
|
action = plans.NoOp
|
||||||
|
|
||||||
default:
|
|
||||||
action = plans.Update
|
|
||||||
}
|
}
|
||||||
|
|
||||||
change := &plans.OutputChange{
|
change := &plans.OutputChange{
|
||||||
|
|
Loading…
Reference in New Issue