Skip to content

Commit

Permalink
[WIP] core: data resource lifecycle
Browse files Browse the repository at this point in the history
  • Loading branch information
apparentlymart committed May 2, 2016
1 parent 3a6bbfd commit 2491702
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 2 deletions.
52 changes: 52 additions & 0 deletions terraform/eval_data_resource_init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package terraform

import (
"fmt"
"log"
)

// EvalDataResourceInit is an EvalNode implementation that initializes
// a data resource's state from its configuration, once it's complete.
type EvalDataResourceInit struct {
State **InstanceState
Config **ResourceConfig
Info *InstanceInfo
}

func (n *EvalDataResourceInit) Eval(ctx EvalContext) (interface{}, error) {
// TODO: test

// If we already have a state then we don't need to do anything.
if *n.State != nil {
log.Printf("[TRACE] %s: skipping init: state already present", n.Info.Id)
return nil, nil
}

config := *n.Config
if config == nil {
// Should never happen
panic(fmt.Errorf("EvalDataResourceInit for %s given nil ResourceConfig", n.Info.HumanId()))
}

// We can't initialize until our config has been completely interpolated.
// If a data resource depends on a not-yet-created managed resource then
// we'll exit here during Refresh and then visit again during Apply,
// at which point the dependencies should all be ready.
if config.ComputedKeys != nil && len(config.ComputedKeys) > 0 {
log.Printf("[TRACE] %s: skipping init: config has computed attributes", n.Info.Id)
return nil, nil
}

state := &InstanceState{
Attributes: map[string]string{},
}

for k, _ := range config.Raw {
v, _ := config.GetRaw(k)
log.Printf("config %#v = %#v\n", k, v)
}

*n.State = state

return nil, nil
}
54 changes: 52 additions & 2 deletions terraform/transform_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,11 +586,61 @@ func (n *graphNodeExpandedResource) managedResourceEvalNodes(resource *Resource,

func (n *graphNodeExpandedResource) dataResourceEvalNodes(resource *Resource, info *InstanceInfo, resourceConfig *ResourceConfig) []EvalNode {
//var diff *InstanceDiff
//var provider ResourceProvider
//var state *InstanceState
var provider ResourceProvider
var state *InstanceState
var config *ResourceConfig

nodes := make([]EvalNode, 0, 5)

// Refresh the resource
nodes = append(nodes, &EvalOpFilter{
Ops: []walkOperation{walkRefresh},
Node: &EvalSequence{
Nodes: []EvalNode{
&EvalGetProvider{
Name: n.ProvidedBy()[0],
Output: &provider,
},
&EvalReadState{
Name: n.stateId(),
Output: &state,
},
&EvalInterpolate{
Config: n.Resource.RawConfig.Copy(),
Resource: resource,
Output: &config,
},
&EvalDataResourceInit{
State: &state,
Config: &config,
Info: info,
},
&EvalRefresh{
Info: info,
Provider: &provider,
State: &state,
Output: &state,
},
&EvalWriteState{
Name: n.stateId(),
ResourceType: n.Resource.Type,
Provider: n.Resource.Provider,
Dependencies: n.StateDependencies(),
State: &state,
},
},
},
})

// TODO: Diff should check if we have a state yet, and if not
// produce a creation diff for our resource that we can then
// process during Apply.

// TODO: Apply should check whether we have a creation diff,
// and if so repeat the same steps we would do during Refresh
// so that we'll populate our state before any of our dependencies
// need access to it.

return nodes
}

Expand Down

0 comments on commit 2491702

Please sign in to comment.