terraform: Plan should use module.Tree
This commit is contained in:
parent
672bf58337
commit
718fb42f4b
|
@ -0,0 +1,54 @@
|
||||||
|
package module
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/gob"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t *Tree) GobDecode(bs []byte) error {
|
||||||
|
t.lock.Lock()
|
||||||
|
defer t.lock.Unlock()
|
||||||
|
|
||||||
|
// Decode the gob data
|
||||||
|
var data treeGob
|
||||||
|
dec := gob.NewDecoder(bytes.NewReader(bs))
|
||||||
|
if err := dec.Decode(&data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the fields
|
||||||
|
t.name = data.Name
|
||||||
|
t.config = data.Config
|
||||||
|
t.children = data.Children
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tree) GobEncode() ([]byte, error) {
|
||||||
|
data := &treeGob{
|
||||||
|
Config: t.config,
|
||||||
|
Children: t.children,
|
||||||
|
Name: t.name,
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
enc := gob.NewEncoder(&buf)
|
||||||
|
if err := enc.Encode(data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// treeGob is used as a structure to Gob encode a tree.
|
||||||
|
//
|
||||||
|
// This structure is private so it can't be referenced but the fields are
|
||||||
|
// public, allowing Gob to properly encode this. When we decode this, we are
|
||||||
|
// able to turn it into a Tree.
|
||||||
|
type treeGob struct {
|
||||||
|
Config *config.Config
|
||||||
|
Children map[string]*Tree
|
||||||
|
Name string
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package module
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/gob"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTreeEncodeDecodeGob(t *testing.T) {
|
||||||
|
storage := testStorage(t)
|
||||||
|
tree := NewTree("", testConfig(t, "basic"))
|
||||||
|
|
||||||
|
// This should get things
|
||||||
|
if err := tree.Load(storage, GetModeGet); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode it.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
enc := gob.NewEncoder(&buf)
|
||||||
|
if err := enc.Encode(tree); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dec := gob.NewDecoder(&buf)
|
||||||
|
var actual Tree
|
||||||
|
if err := dec.Decode(&actual); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actualStr := strings.TrimSpace(actual.String())
|
||||||
|
expectedStr := strings.TrimSpace(tree.String())
|
||||||
|
if actualStr != expectedStr {
|
||||||
|
t.Fatalf("\n%s\n\nexpected:\n\n%s", actualStr, expectedStr)
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,6 @@ type genericWalkFunc func(*walkContext, *Resource) error
|
||||||
//
|
//
|
||||||
// Additionally, a context can be created from a Plan using Plan.Context.
|
// Additionally, a context can be created from a Plan using Plan.Context.
|
||||||
type Context struct {
|
type Context struct {
|
||||||
config *config.Config
|
|
||||||
module *module.Tree
|
module *module.Tree
|
||||||
diff *Diff
|
diff *Diff
|
||||||
hooks []Hook
|
hooks []Hook
|
||||||
|
@ -74,13 +73,7 @@ func NewContext(opts *ContextOpts) *Context {
|
||||||
}
|
}
|
||||||
parCh := make(chan struct{}, par)
|
parCh := make(chan struct{}, par)
|
||||||
|
|
||||||
var config *config.Config
|
|
||||||
if opts.Module != nil {
|
|
||||||
config = opts.Module.Config()
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Context{
|
return &Context{
|
||||||
config: config,
|
|
||||||
diff: opts.Diff,
|
diff: opts.Diff,
|
||||||
hooks: hooks,
|
hooks: hooks,
|
||||||
module: opts.Module,
|
module: opts.Module,
|
||||||
|
@ -139,7 +132,7 @@ func (c *Context) Plan(opts *PlanOpts) (*Plan, error) {
|
||||||
defer c.releaseRun(v)
|
defer c.releaseRun(v)
|
||||||
|
|
||||||
p := &Plan{
|
p := &Plan{
|
||||||
Config: c.config,
|
Module: c.module,
|
||||||
Vars: c.variables,
|
Vars: c.variables,
|
||||||
State: c.state,
|
State: c.state,
|
||||||
}
|
}
|
||||||
|
@ -223,12 +216,12 @@ func (c *Context) Validate() ([]string, []error) {
|
||||||
var rerr *multierror.Error
|
var rerr *multierror.Error
|
||||||
|
|
||||||
// Validate the configuration itself
|
// Validate the configuration itself
|
||||||
if err := c.config.Validate(); err != nil {
|
if err := c.module.Config().Validate(); err != nil {
|
||||||
rerr = multierror.ErrorAppend(rerr, err)
|
rerr = multierror.ErrorAppend(rerr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the user variables
|
// Validate the user variables
|
||||||
if errs := smcUserVariables(c.config, c.variables); len(errs) > 0 {
|
if errs := smcUserVariables(c.module.Config(), c.variables); len(errs) > 0 {
|
||||||
rerr = multierror.ErrorAppend(rerr, errs...)
|
rerr = multierror.ErrorAppend(rerr, errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,7 +1253,7 @@ func (c *walkContext) computeResourceMultiVariable(
|
||||||
// Get the resource from the configuration so we can know how
|
// Get the resource from the configuration so we can know how
|
||||||
// many of the resource there is.
|
// many of the resource there is.
|
||||||
var cr *config.Resource
|
var cr *config.Resource
|
||||||
for _, r := range c.Context.config.Resources {
|
for _, r := range c.Context.module.Config().Resources {
|
||||||
if r.Id() == v.ResourceId() {
|
if r.Id() == v.ResourceId() {
|
||||||
cr = r
|
cr = r
|
||||||
break
|
break
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/config"
|
|
||||||
"github.com/hashicorp/terraform/config/module"
|
"github.com/hashicorp/terraform/config/module"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,8 +30,8 @@ type PlanOpts struct {
|
||||||
// Plan represents a single Terraform execution plan, which contains
|
// Plan represents a single Terraform execution plan, which contains
|
||||||
// all the information necessary to make an infrastructure change.
|
// all the information necessary to make an infrastructure change.
|
||||||
type Plan struct {
|
type Plan struct {
|
||||||
Config *config.Config
|
|
||||||
Diff *Diff
|
Diff *Diff
|
||||||
|
Module *module.Tree
|
||||||
State *State
|
State *State
|
||||||
Vars map[string]string
|
Vars map[string]string
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ type Plan struct {
|
||||||
// Diff, State, Variables.
|
// Diff, State, Variables.
|
||||||
func (p *Plan) Context(opts *ContextOpts) *Context {
|
func (p *Plan) Context(opts *ContextOpts) *Context {
|
||||||
opts.Diff = p.Diff
|
opts.Diff = p.Diff
|
||||||
opts.Module = module.NewTree("", p.Config) // TODO: compat
|
opts.Module = p.Module
|
||||||
opts.State = p.State
|
opts.State = p.State
|
||||||
opts.Variables = p.Vars
|
opts.Variables = p.Vars
|
||||||
return NewContext(opts)
|
return NewContext(opts)
|
||||||
|
@ -62,10 +61,6 @@ func (p *Plan) String() string {
|
||||||
|
|
||||||
func (p *Plan) init() {
|
func (p *Plan) init() {
|
||||||
p.once.Do(func() {
|
p.once.Do(func() {
|
||||||
if p.Config == nil {
|
|
||||||
p.Config = new(config.Config)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Diff == nil {
|
if p.Diff == nil {
|
||||||
p.Diff = new(Diff)
|
p.Diff = new(Diff)
|
||||||
p.Diff.init()
|
p.Diff.init()
|
||||||
|
|
|
@ -2,14 +2,14 @@ package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"reflect"
|
"strings"
|
||||||
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestReadWritePlan(t *testing.T) {
|
func TestReadWritePlan(t *testing.T) {
|
||||||
plan := &Plan{
|
plan := &Plan{
|
||||||
Config: testConfig(t, "new-good"),
|
Module: testModule(t, "new-good"),
|
||||||
Diff: &Diff{
|
Diff: &Diff{
|
||||||
Modules: []*ModuleDiff{
|
Modules: []*ModuleDiff{
|
||||||
&ModuleDiff{
|
&ModuleDiff{
|
||||||
|
@ -65,9 +65,9 @@ func TestReadWritePlan(t *testing.T) {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
println(reflect.DeepEqual(actual.Config.Resources, plan.Config.Resources))
|
actualStr := strings.TrimSpace(actual.String())
|
||||||
|
expectedStr := strings.TrimSpace(plan.String())
|
||||||
if !reflect.DeepEqual(actual, plan) {
|
if actualStr != expectedStr {
|
||||||
t.Fatalf("bad: %#v", actual)
|
t.Fatalf("bad:\n\n%s\n\nexpected:\n\n%s", actualStr, expectedStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue