Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

more module expansion foundation #24389

Merged
merged 6 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion addrs/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ func (r AbsResource) Instance(key InstanceKey) AbsResourceInstance {
}
}

// Config returns the unexpanded ConfigResource for this AbsResource.
func (r AbsResource) Config() ConfigResource {
return ConfigResource{
Module: r.Module.Module(),
Resource: r.Resource,
}
}

// TargetContains implements Targetable by returning true if the given other
// address is either equal to the receiver or is an instance of the
// receiver.
Expand Down Expand Up @@ -300,7 +308,7 @@ func (r ConfigResource) TargetContains(other Targetable) bool {
// We'll use our stringification as a cheat-ish way to test for equality.
return to.String() == r.String()
case AbsResource:
return r.TargetContains(ConfigResource{Module: to.Module.Module(), Resource: to.Resource})
return r.TargetContains(to.Config())
case AbsResourceInstance:
return r.TargetContains(to.ContainingResource())
default:
Expand Down
29 changes: 15 additions & 14 deletions command/format/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,19 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
instances := []obj{}

addr := m.Resources[key].Addr
resAddr := addr.Resource

taintStr := ""
if v.Current != nil && v.Current.Status == 'T' {
taintStr = " (tainted)"
}

instances = append(instances,
obj{fmt.Sprintf("# %s:%s\n", addr.Absolute(m.Addr).Instance(k), taintStr), v.Current})
obj{fmt.Sprintf("# %s:%s\n", addr.Instance(k), taintStr), v.Current})

for dk, v := range v.Deposed {
instances = append(instances,
obj{fmt.Sprintf("# %s: (deposed object %s)\n", addr.Absolute(m.Addr).Instance(k), dk), v})
obj{fmt.Sprintf("# %s: (deposed object %s)\n", addr.Instance(k), dk), v})
}

// Sort the instances for consistent output.
Expand Down Expand Up @@ -150,44 +151,44 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
continue
}

switch addr.Mode {
switch resAddr.Mode {
case addrs.ManagedResourceMode:
schema, _ = schemas.ResourceTypeConfig(
provider,
addr.Mode,
addr.Type,
resAddr.Mode,
resAddr.Type,
)
if schema == nil {
p.buf.WriteString(fmt.Sprintf(
"# missing schema for provider %q resource type %s\n\n", provider, addr.Type))
"# missing schema for provider %q resource type %s\n\n", provider, resAddr.Type))
continue
}

p.buf.WriteString(fmt.Sprintf(
"resource %q %q {",
addr.Type,
addr.Name,
resAddr.Type,
resAddr.Name,
))
case addrs.DataResourceMode:
schema, _ = schemas.ResourceTypeConfig(
provider,
addr.Mode,
addr.Type,
resAddr.Mode,
resAddr.Type,
)
if schema == nil {
p.buf.WriteString(fmt.Sprintf(
"# missing schema for provider %q data source %s\n\n", provider, addr.Type))
"# missing schema for provider %q data source %s\n\n", provider, resAddr.Type))
continue
}

p.buf.WriteString(fmt.Sprintf(
"data %q %q {",
addr.Type,
addr.Name,
resAddr.Type,
resAddr.Name,
))
default:
// should never happen, since the above is exhaustive
p.buf.WriteString(addr.String())
p.buf.WriteString(resAddr.String())
}

val, err := instance.Decode(schema.ImpliedType())
Expand Down
20 changes: 11 additions & 9 deletions command/jsonstate/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,22 +255,24 @@ func marshalResources(resources map[string]*states.Resource, module addrs.Module
for _, r := range resources {
for k, ri := range r.Instances {

resAddr := r.Addr.Resource

current := resource{
Address: r.Addr.Absolute(module).Instance(k).String(),
Type: r.Addr.Type,
Name: r.Addr.Name,
Address: r.Addr.Instance(k).String(),
Type: resAddr.Type,
Name: resAddr.Name,
ProviderName: r.ProviderConfig.Provider.LegacyString(),
}

switch r.Addr.Mode {
switch resAddr.Mode {
case addrs.ManagedResourceMode:
current.Mode = "managed"
case addrs.DataResourceMode:
current.Mode = "data"
default:
return ret, fmt.Errorf("resource %s has an unsupported mode %s",
r.Addr.String(),
r.Addr.Mode.String(),
resAddr.String(),
resAddr.Mode.String(),
)
}

Expand All @@ -280,16 +282,16 @@ func marshalResources(resources map[string]*states.Resource, module addrs.Module

schema, _ := schemas.ResourceTypeConfig(
r.ProviderConfig.Provider,
r.Addr.Mode,
r.Addr.Type,
resAddr.Mode,
resAddr.Type,
)

// It is possible that the only instance is deposed
if ri.Current != nil {
current.SchemaVersion = ri.Current.SchemaVersion

if schema == nil {
return nil, fmt.Errorf("no schema found for %s", r.Addr.String())
return nil, fmt.Errorf("no schema found for %s", resAddr.String())
}
riObj, err := ri.Current.Decode(schema.ImpliedType())
if err != nil {
Expand Down
50 changes: 30 additions & 20 deletions command/jsonstate/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,12 @@ func TestMarshalResources(t *testing.T) {
"single resource": {
map[string]*states.Resource{
"test_thing.baz": {
Addr: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
Addr: addrs.AbsResource{
Resource: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
},
},
EachMode: states.NoEach,
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
Expand Down Expand Up @@ -228,10 +230,12 @@ func TestMarshalResources(t *testing.T) {
"resource with count": {
map[string]*states.Resource{
"test_thing.bar": {
Addr: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
Addr: addrs.AbsResource{
Resource: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
},
},
EachMode: states.EachList,
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
Expand Down Expand Up @@ -270,10 +274,12 @@ func TestMarshalResources(t *testing.T) {
"resource with for_each": {
map[string]*states.Resource{
"test_thing.bar": {
Addr: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
Addr: addrs.AbsResource{
Resource: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
},
},
EachMode: states.EachMap,
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
Expand Down Expand Up @@ -312,10 +318,12 @@ func TestMarshalResources(t *testing.T) {
"deposed resource": {
map[string]*states.Resource{
"test_thing.baz": {
Addr: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
Addr: addrs.AbsResource{
Resource: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
},
},
EachMode: states.NoEach,
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
Expand Down Expand Up @@ -356,10 +364,12 @@ func TestMarshalResources(t *testing.T) {
"deposed and current resource": {
map[string]*states.Resource{
"test_thing.baz": {
Addr: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
Addr: addrs.AbsResource{
Resource: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "bar",
},
},
EachMode: states.NoEach,
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
Expand Down
2 changes: 1 addition & 1 deletion command/state_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (c *StateMeta) collectModuleResourceInstances(ms *states.Module) []addrs.Ab
func (c *StateMeta) collectResourceInstances(moduleAddr addrs.ModuleInstance, rs *states.Resource) []addrs.AbsResourceInstance {
var ret []addrs.AbsResourceInstance
for key := range rs.Instances {
ret = append(ret, rs.Addr.Instance(key).Absolute(moduleAddr))
ret = append(ret, rs.Addr.Instance(key))
}
return ret
}
2 changes: 1 addition & 1 deletion command/state_mv.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func (c *StateMvCommand) Run(args []string) int {
ssFrom.RemoveResource(addrFrom)

// Update the address before adding it to the state.
rs.Addr = addrTo.Resource
rs.Addr = addrTo
stateTo.Module(addrTo.Module).Resources[addrTo.Resource.String()] = rs
}

Expand Down
6 changes: 3 additions & 3 deletions helper/resource/state_shim.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ func shimNewState(newState *states.State, providers map[string]terraform.Resourc
}

for _, res := range newMod.Resources {
resType := res.Addr.Type
resType := res.Addr.Resource.Type
providerType := res.ProviderConfig.Provider.Type

resource := getResource(providers, providerType, res.Addr)
resource := getResource(providers, providerType, res.Addr.Resource)

for key, i := range res.Instances {
resState := &terraform.ResourceState{
Expand Down Expand Up @@ -103,7 +103,7 @@ func shimNewState(newState *states.State, providers map[string]terraform.Resourc
idx = "." + key.String()
}

mod.Resources[res.Addr.String()+idx] = resState
mod.Resources[res.Addr.Resource.String()+idx] = resState
}

// add any deposed instances
Expand Down
4 changes: 2 additions & 2 deletions states/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (ms *Module) SetResourceMeta(addr addrs.Resource, eachMode EachMode, provid
rs := ms.Resource(addr)
if rs == nil {
rs = &Resource{
Addr: addr,
Addr: addr.Absolute(ms.Addr),
Instances: map[addrs.InstanceKey]*ResourceInstance{},
}
ms.Resources[addr.String()] = rs
Expand Down Expand Up @@ -295,7 +295,7 @@ func (ms *Module) RemoveLocalValue(name string) {
func (ms *Module) PruneResourceHusks() {
for _, rs := range ms.Resources {
if len(rs.Instances) == 0 {
ms.RemoveResource(rs.Addr)
ms.RemoveResource(rs.Addr.Resource)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions states/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (

// Resource represents the state of a resource.
type Resource struct {
// Addr is the module-relative address for the resource this state object
// Addr is the absolute address for the resource this state object
// belongs to.
Addr addrs.Resource
Addr addrs.AbsResource

// EachMode is the multi-instance mode currently in use for this resource,
// or NoEach if this is a single-instance resource. This dictates what
Expand Down
23 changes: 23 additions & 0 deletions states/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ func (s *State) Module(addr addrs.ModuleInstance) *Module {
return s.Modules[addr.String()]
}

// ModuleInstances returns the set of Module states that matches the given path.
func (s *State) ModuleInstances(addr addrs.Module) []*Module {
var ms []*Module
for _, m := range s.Modules {
if m.Addr.Module().Equal(addr) {
ms = append(ms, m)
}
}
return ms
}

// RemoveModule removes the module with the given address from the state,
// unless it is the root module. The root module cannot be deleted, and so
// this method will panic if that is attempted.
Expand Down Expand Up @@ -133,6 +144,18 @@ func (s *State) Resource(addr addrs.AbsResource) *Resource {
return ms.Resource(addr.Resource)
}

// Resources returns the set of resources that match the given configuration path.
func (s *State) Resources(addr addrs.ConfigResource) []*Resource {
var ret []*Resource
for _, m := range s.ModuleInstances(addr.Module) {
r := m.Resource(addr.Resource)
if r != nil {
ret = append(ret, r)
}
}
return ret
}

// ResourceInstance returns the state for the resource instance with the given
// address, or nil if no such resource is tracked in the state.
func (s *State) ResourceInstance(addr addrs.AbsResourceInstance) *ResourceInstance {
Expand Down
2 changes: 1 addition & 1 deletion states/state_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (m *Module) testString() string {
addrsOrder := make([]addrs.AbsResourceInstance, 0, len(m.Resources))
for _, rs := range m.Resources {
for ik := range rs.Instances {
addrsOrder = append(addrsOrder, rs.Addr.Instance(ik).Absolute(addrs.RootModuleInstance))
addrsOrder = append(addrsOrder, rs.Addr.Instance(ik))
}
}

Expand Down
3 changes: 2 additions & 1 deletion states/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ func TestState(t *testing.T) {
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "baz",
},
}.Absolute(addrs.RootModuleInstance),

EachMode: EachList,
Instances: map[addrs.InstanceKey]*ResourceInstance{
addrs.IntKey(0): {
Expand Down
2 changes: 1 addition & 1 deletion states/statefile/version4.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ func writeStateV4(file *File, w io.Writer) tfdiags.Diagnostics {
for _, ms := range file.State.Modules {
moduleAddr := ms.Addr
for _, rs := range ms.Resources {
resourceAddr := rs.Addr
resourceAddr := rs.Addr.Resource

var mode string
switch resourceAddr.Mode {
Expand Down
Loading