Merge pull request #9496 from hashicorp/b-apply-data

terraform: new apply resource node supports data sources
This commit is contained in:
Mitchell Hashimoto 2016-10-20 22:43:21 -07:00 committed by GitHub
commit 0fdedbd003
4 changed files with 144 additions and 4 deletions

View File

@ -508,6 +508,38 @@ func TestContext2Apply_destroyComputed(t *testing.T) {
}
}
func TestContext2Apply_dataBasic(t *testing.T) {
m := testModule(t, "apply-data-basic")
p := testProvider("null")
p.ApplyFn = testApplyFn
p.DiffFn = testDiffFn
p.ReadDataApplyReturn = &InstanceState{ID: "yo"}
ctx := testContext2(t, &ContextOpts{
Module: m,
Providers: map[string]ResourceProviderFactory{
"null": testProviderFuncFixed(p),
},
})
if p, err := ctx.Plan(); err != nil {
t.Fatalf("err: %s", err)
} else {
t.Logf(p.String())
}
state, err := ctx.Apply()
if err != nil {
t.Fatalf("err: %s", err)
}
actual := strings.TrimSpace(state.String())
expected := strings.TrimSpace(testTerraformApplyDataBasicStr)
if actual != expected {
t.Fatalf("bad: \n%s", actual)
}
}
func TestContext2Apply_destroyData(t *testing.T) {
m := testModule(t, "apply-destroy-data-resource")
p := testProvider("null")

View File

@ -2,6 +2,8 @@ package terraform
import (
"fmt"
"github.com/hashicorp/terraform/config"
)
// NodeApplyableResource represents a resource that is "applyable":
@ -49,6 +51,106 @@ func (n *NodeApplyableResource) EvalTree() EvalNode {
stateDeps = oldN.StateDependencies()
}
// Eval info is different depending on what kind of resource this is
switch n.Config.Mode {
case config.ManagedResourceMode:
return n.evalTreeManagedResource(
stateId, info, resource, stateDeps,
)
case config.DataResourceMode:
return n.evalTreeDataResource(
stateId, info, resource, stateDeps)
default:
panic(fmt.Errorf("unsupported resource mode %s", n.Config.Mode))
}
}
func (n *NodeApplyableResource) evalTreeDataResource(
stateId string, info *InstanceInfo,
resource *Resource, stateDeps []string) EvalNode {
var provider ResourceProvider
var config *ResourceConfig
var diff *InstanceDiff
var state *InstanceState
return &EvalSequence{
Nodes: []EvalNode{
// Get the saved diff for apply
&EvalReadDiff{
Name: stateId,
Diff: &diff,
},
// Stop here if we don't actually have a diff
&EvalIf{
If: func(ctx EvalContext) (bool, error) {
if diff == nil {
return true, EvalEarlyExitError{}
}
if diff.GetAttributesLen() == 0 {
return true, EvalEarlyExitError{}
}
return true, nil
},
Then: EvalNoop{},
},
// We need to re-interpolate the config here, rather than
// just using the diff's values directly, because we've
// potentially learned more variable values during the
// apply pass that weren't known when the diff was produced.
&EvalInterpolate{
Config: n.Config.RawConfig.Copy(),
Resource: resource,
Output: &config,
},
&EvalGetProvider{
Name: n.ProvidedBy()[0],
Output: &provider,
},
// Make a new diff with our newly-interpolated config.
&EvalReadDataDiff{
Info: info,
Config: &config,
Previous: &diff,
Provider: &provider,
Output: &diff,
},
&EvalReadDataApply{
Info: info,
Diff: &diff,
Provider: &provider,
Output: &state,
},
&EvalWriteState{
Name: stateId,
ResourceType: n.Config.Type,
Provider: n.Config.Provider,
Dependencies: stateDeps,
State: &state,
},
// Clear the diff now that we've applied it, so
// later nodes won't see a diff that's now a no-op.
&EvalWriteDiff{
Name: stateId,
Diff: nil,
},
&EvalUpdateStateHook{},
},
}
}
func (n *NodeApplyableResource) evalTreeManagedResource(
stateId string, info *InstanceInfo,
resource *Resource, stateDeps []string) EvalNode {
// Declare a bunch of variables that are used for state during
// evaluation. Most of this are written to by-address below.
var provider ResourceProvider

View File

@ -25,13 +25,13 @@ func TestMain(m *testing.M) {
// Experimental features
xNewApply := flag.Bool("Xnew-apply", false, "Experiment: new apply graph")
// Normal features
shadow := flag.Bool("shadow", true, "Enable shadow graph")
flag.Parse()
// Setup experimental features
X_newApply = *xNewApply
if X_newApply {
println("Xnew-apply enabled")
}
if testing.Verbose() {
// if we're verbose, use the logging requested by TF_LOG
@ -48,7 +48,7 @@ func TestMain(m *testing.M) {
contextTestDeepCopyOnPlan = true
// Shadow the new graphs
contextTestShadow = true
contextTestShadow = *shadow
os.Exit(m.Run())
}
@ -257,6 +257,11 @@ aws_instance.foo:
type = aws_instance
`
const testTerraformApplyDataBasicStr = `
data.null_data_source.testing:
ID = yo
`
const testTerraformApplyRefCountStr = `
aws_instance.bar:
ID = foo

View File

@ -0,0 +1 @@
data "null_data_source" "testing" {}