terraform: start eval stuff, untested

This commit is contained in:
Mitchell Hashimoto 2015-02-03 10:43:18 +01:00
parent a73f939ee9
commit 128c07e504
7 changed files with 189 additions and 0 deletions

33
terraform/eval.go Normal file
View File

@ -0,0 +1,33 @@
package terraform
// EvalContext is the interface that is given to eval nodes to execute.
type EvalContext interface {
// InitProvider initializes the provider with the given name and
// returns the implementation of the resource provider or an error.
InitProvider(string) (ResourceProvider, error)
// Provider gets the provider instance with the given name (already
// initialized) or returns nil if the provider isn't initialized.
Provider(string) ResourceProvider
}
// EvalNode is the interface that must be implemented by graph nodes to
// evaluate/execute.
type EvalNode interface {
// Args returns the arguments for this node as well as the list of
// expected types. The expected types are only used for type checking
// and not used at runtime.
Args() ([]EvalNode, []EvalType)
// Eval evaluates this node with the given context.
Eval(EvalContext) (interface{}, error)
// Type returns the type that will be returned by this node.
Type() EvalType
}
// GraphNodeEvalable is the interface that graph nodes must implement
// to enable valuation.
type GraphNodeEvalable interface {
EvalTree() EvalNode
}

View File

@ -0,0 +1,23 @@
package terraform
import (
"github.com/hashicorp/terraform/config"
)
// EvalInterpolate is an EvalNode implementation that takes a raw
// configuration and interpolates it.
type EvalInterpolate struct {
Config *config.RawConfig
}
func (n *EvalInterpolate) Args() ([]EvalNode, []EvalType) {
return nil, nil
}
func (n *EvalInterpolate) Eval(ctx EvalContext) (interface{}, error) {
return nil, nil
}
func (n *EvalInterpolate) Type() EvalType {
return EvalTypeConfig
}

View File

@ -0,0 +1,67 @@
package terraform
import (
"fmt"
)
// EvalConfigProvider is an EvalNode implementation that configures
// a provider that is already initialized and retrieved.
type EvalConfigProvider struct {
Provider EvalNode
Config EvalNode
}
func (n *EvalConfigProvider) Args() ([]EvalNode, []EvalType) {
return []EvalNode{n.Provider, n.Config},
[]EvalType{EvalTypeResourceProvider, EvalTypeConfig}
}
func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) {
return nil, nil
}
func (n *EvalConfigProvider) Type() EvalType {
return EvalTypeNull
}
// EvalInitProvider is an EvalNode implementation that initializes a provider
// and returns nothing. The provider can be retrieved again with the
// EvalGetProvider node.
type EvalInitProvider struct {
Name string
}
func (n *EvalInitProvider) Args() ([]EvalNode, []EvalType) {
return nil, nil
}
func (n *EvalInitProvider) Eval(ctx EvalContext) (interface{}, error) {
return ctx.InitProvider(n.Name)
}
func (n *EvalInitProvider) Type() EvalType {
return EvalTypeNull
}
// EvalGetProvider is an EvalNode implementation that retrieves an already
// initialized provider instance for the given name.
type EvalGetProvider struct {
Name string
}
func (n *EvalGetProvider) Args() ([]EvalNode, []EvalType) {
return nil, nil
}
func (n *EvalGetProvider) Eval(ctx EvalContext) (interface{}, error) {
result := ctx.Provider(n.Name)
if result == nil {
return nil, fmt.Errorf("provider %s not initialized", n.Name)
}
return result, nil
}
func (n *EvalGetProvider) Type() EvalType {
return EvalTypeResourceProvider
}

19
terraform/eval_type.go Normal file
View File

@ -0,0 +1,19 @@
package terraform
// This separate file for EvalType exists so that stringer below
// can work without error. See this thread for more details:
//
// http://comments.gmane.org/gmane.comp.lang.go.general/148740
//go:generate stringer -type=EvalType eval_type.go
// EvalType is the type of any value returned by an EvalNode. This is
// used for type checking.
type EvalType uint32
const (
EvalTypeInvalid EvalType = 0
EvalTypeNull EvalType = 1 << iota
EvalTypeConfig
EvalTypeResourceProvider
)

View File

@ -0,0 +1,34 @@
// generated by stringer -type=EvalType eval_type.go; DO NOT EDIT
package terraform
import "fmt"
const (
_EvalType_name_0 = "EvalTypeInvalid"
_EvalType_name_1 = "EvalTypeNull"
_EvalType_name_2 = "EvalTypeConfig"
_EvalType_name_3 = "EvalTypeResourceProvider"
)
var (
_EvalType_index_0 = [...]uint8{0, 15}
_EvalType_index_1 = [...]uint8{0, 12}
_EvalType_index_2 = [...]uint8{0, 14}
_EvalType_index_3 = [...]uint8{0, 24}
)
func (i EvalType) String() string {
switch {
case i == 0:
return _EvalType_name_0
case i == 2:
return _EvalType_name_1
case i == 4:
return _EvalType_name_2
case i == 8:
return _EvalType_name_3
default:
return fmt.Sprintf("EvalType(%d)", i)
}
}

View File

@ -73,6 +73,14 @@ func (n *GraphNodeConfigProvider) DependentOn() []string {
return result
}
// GraphNodeEvalable impl.
func (n *GraphNodeConfigProvider) EvalTree() EvalNode {
return &EvalConfigProvider{
Provider: &EvalGetProvider{Name: n.Provider.Name},
Config: &EvalInterpolate{Config: n.Provider.RawConfig},
}
}
// GraphNodeProvider implementation
func (n *GraphNodeConfigProvider) ProviderName() string {
return n.Provider.Name

View File

@ -100,6 +100,11 @@ func (n *graphNodeMissingProvider) Name() string {
return fmt.Sprintf("provider.%s", n.ProviderNameValue)
}
// GraphNodeEvalable impl.
func (n *graphNodeMissingProvider) EvalTree() EvalNode {
return &EvalInitProvider{Name: n.ProviderNameValue}
}
func (n *graphNodeMissingProvider) ProviderName() string {
return n.ProviderNameValue
}