terraform: resource => module

This commit is contained in:
Mitchell Hashimoto 2016-04-12 09:46:16 -07:00
parent d3fcfcc027
commit e497c26517
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
2 changed files with 66 additions and 13 deletions

View File

@ -27,16 +27,22 @@ import (
// represents a single instance (primary). Example: // represents a single instance (primary). Example:
// "aws_instance.foo" can be moved to "aws_instance.bar.tainted" // "aws_instance.foo" can be moved to "aws_instance.bar.tainted"
// //
func (s *State) Add(addrRaw string, raw interface{}) error { func (s *State) Add(fromAddrRaw string, toAddrRaw string, raw interface{}) error {
// Parse the address // Parse the address
addr, err := ParseResourceAddress(addrRaw) toAddr, err := ParseResourceAddress(toAddrRaw)
if err != nil {
return err
}
// Parse the from address
fromAddr, err := ParseResourceAddress(fromAddrRaw)
if err != nil { if err != nil {
return err return err
} }
// Determine the types // Determine the types
from := detectValueAddLoc(raw) from := detectValueAddLoc(raw)
to := detectAddrAddLoc(addr) to := detectAddrAddLoc(toAddr)
// Find the function to do this // Find the function to do this
fromMap, ok := stateAddFuncs[from] fromMap, ok := stateAddFuncs[from]
@ -45,11 +51,11 @@ func (s *State) Add(addrRaw string, raw interface{}) error {
} }
f, ok := fromMap[to] f, ok := fromMap[to]
if !ok { if !ok {
return fmt.Errorf("invalid destination: %s (%d)", addr, to) return fmt.Errorf("invalid destination: %s (%d)", toAddr, to)
} }
// Call the migrator // Call the migrator
if err := f(s, addr, raw); err != nil { if err := f(s, fromAddr, toAddr, raw); err != nil {
return err return err
} }
@ -58,7 +64,7 @@ func (s *State) Add(addrRaw string, raw interface{}) error {
return nil return nil
} }
func stateAddFunc_Module_Module(s *State, addr *ResourceAddress, raw interface{}) error { func stateAddFunc_Module_Module(s *State, fromAddr, addr *ResourceAddress, raw interface{}) error {
src := raw.(*ModuleState).deepcopy() src := raw.(*ModuleState).deepcopy()
// If the target module exists, it is an error // If the target module exists, it is an error
@ -86,7 +92,7 @@ func stateAddFunc_Module_Module(s *State, addr *ResourceAddress, raw interface{}
addrCopy.Index = resourceKey.Index addrCopy.Index = resourceKey.Index
// Perform an add // Perform an add
if err := s.Add(addrCopy.String(), v); err != nil { if err := s.Add(fromAddr.String(), addrCopy.String(), v); err != nil {
return err return err
} }
} }
@ -94,7 +100,17 @@ func stateAddFunc_Module_Module(s *State, addr *ResourceAddress, raw interface{}
return nil return nil
} }
func stateAddFunc_Resource_Resource(s *State, addr *ResourceAddress, raw interface{}) error { func stateAddFunc_Resource_Module(
s *State, from, to *ResourceAddress, raw interface{}) error {
// Build the more specific to addr
addr := *to
addr.Type = from.Type
addr.Name = from.Name
return s.Add(from.String(), addr.String(), raw)
}
func stateAddFunc_Resource_Resource(s *State, fromAddr, addr *ResourceAddress, raw interface{}) error {
src := raw.(*ResourceState).deepcopy() src := raw.(*ResourceState).deepcopy()
// Initialize the resource // Initialize the resource
@ -112,7 +128,7 @@ func stateAddFunc_Resource_Resource(s *State, addr *ResourceAddress, raw interfa
addrCopy := *addr addrCopy := *addr
addrCopy.InstanceType = TypePrimary addrCopy.InstanceType = TypePrimary
addrCopy.InstanceTypeSet = true addrCopy.InstanceTypeSet = true
if err := s.Add(addrCopy.String(), src.Primary); err != nil { if err := s.Add(fromAddr.String(), addrCopy.String(), src.Primary); err != nil {
return err return err
} }
} }
@ -130,7 +146,7 @@ func stateAddFunc_Resource_Resource(s *State, addr *ResourceAddress, raw interfa
return nil return nil
} }
func stateAddFunc_Instance_Instance(s *State, addr *ResourceAddress, raw interface{}) error { func stateAddFunc_Instance_Instance(s *State, fromAddr, addr *ResourceAddress, raw interface{}) error {
src := raw.(*InstanceState).deepcopy() src := raw.(*InstanceState).deepcopy()
// Create the instance // Create the instance
@ -144,7 +160,7 @@ func stateAddFunc_Instance_Instance(s *State, addr *ResourceAddress, raw interfa
} }
// stateAddFunc is the type of function for adding an item to a state // stateAddFunc is the type of function for adding an item to a state
type stateAddFunc func(s *State, addr *ResourceAddress, item interface{}) error type stateAddFunc func(s *State, from, to *ResourceAddress, item interface{}) error
// stateAddFuncs has the full matrix mapping of the state adders. // stateAddFuncs has the full matrix mapping of the state adders.
var stateAddFuncs map[stateAddLoc]map[stateAddLoc]stateAddFunc var stateAddFuncs map[stateAddLoc]map[stateAddLoc]stateAddFunc
@ -155,6 +171,7 @@ func init() {
stateAddModule: stateAddFunc_Module_Module, stateAddModule: stateAddFunc_Module_Module,
}, },
stateAddResource: { stateAddResource: {
stateAddModule: stateAddFunc_Resource_Module,
stateAddResource: stateAddFunc_Resource_Resource, stateAddResource: stateAddFunc_Resource_Resource,
}, },
stateAddInstance: { stateAddInstance: {

View File

@ -7,12 +7,13 @@ import (
func TestStateAdd(t *testing.T) { func TestStateAdd(t *testing.T) {
cases := map[string]struct { cases := map[string]struct {
Err bool Err bool
Address string From, To string
Value interface{} Value interface{}
One, Two *State One, Two *State
}{ }{
"ModuleState => Module Addr (new)": { "ModuleState => Module Addr (new)": {
false, false,
"",
"module.foo", "module.foo",
&ModuleState{ &ModuleState{
Path: rootModulePath, Path: rootModulePath,
@ -60,6 +61,7 @@ func TestStateAdd(t *testing.T) {
"ModuleState w/ outputs and deps => Module Addr (new)": { "ModuleState w/ outputs and deps => Module Addr (new)": {
false, false,
"",
"module.foo", "module.foo",
&ModuleState{ &ModuleState{
Path: rootModulePath, Path: rootModulePath,
@ -115,6 +117,7 @@ func TestStateAdd(t *testing.T) {
"ModuleState => Module Addr (existing)": { "ModuleState => Module Addr (existing)": {
true, true,
"",
"module.foo", "module.foo",
&ModuleState{}, &ModuleState{},
&State{ &State{
@ -137,6 +140,7 @@ func TestStateAdd(t *testing.T) {
"ResourceState => Resource Addr (new)": { "ResourceState => Resource Addr (new)": {
false, false,
"aws_instance.bar",
"aws_instance.foo", "aws_instance.foo",
&ResourceState{ &ResourceState{
Type: "test_instance", Type: "test_instance",
@ -165,6 +169,7 @@ func TestStateAdd(t *testing.T) {
"ResourceState w/ deps, provider => Resource Addr (new)": { "ResourceState w/ deps, provider => Resource Addr (new)": {
false, false,
"aws_instance.bar",
"aws_instance.foo", "aws_instance.foo",
&ResourceState{ &ResourceState{
Type: "test_instance", Type: "test_instance",
@ -197,6 +202,7 @@ func TestStateAdd(t *testing.T) {
"ResourceState w/ tainted => Resource Addr (new)": { "ResourceState w/ tainted => Resource Addr (new)": {
false, false,
"aws_instance.bar",
"aws_instance.foo", "aws_instance.foo",
&ResourceState{ &ResourceState{
Type: "test_instance", Type: "test_instance",
@ -230,6 +236,7 @@ func TestStateAdd(t *testing.T) {
"ResourceState => Resource Addr (existing)": { "ResourceState => Resource Addr (existing)": {
true, true,
"aws_instance.bar",
"aws_instance.foo", "aws_instance.foo",
&ResourceState{ &ResourceState{
Type: "test_instance", Type: "test_instance",
@ -255,6 +262,35 @@ func TestStateAdd(t *testing.T) {
}, },
nil, nil,
}, },
"ResourceState => Module (existing)": {
false,
"aws_instance.bar",
"module.foo",
&ResourceState{
Type: "test_instance",
Primary: &InstanceState{
ID: "foo",
},
},
&State{},
&State{
Modules: []*ModuleState{
&ModuleState{
Path: []string{"root", "foo"},
Resources: map[string]*ResourceState{
"aws_instance.bar": &ResourceState{
Type: "test_instance",
Primary: &InstanceState{
ID: "foo",
},
},
},
},
},
},
},
} }
for k, tc := range cases { for k, tc := range cases {
@ -265,7 +301,7 @@ func TestStateAdd(t *testing.T) {
} }
// Add the value // Add the value
err := tc.One.Add(tc.Address, tc.Value) err := tc.One.Add(tc.From, tc.To, tc.Value)
if (err != nil) != tc.Err { if (err != nil) != tc.Err {
t.Fatalf("bad: %s\n\n%s", k, err) t.Fatalf("bad: %s\n\n%s", k, err)
} }