Merge pull request #24389 from hashicorp/jbardin/module-expansion-getting-there

more module expansion foundation
This commit is contained in:
James Bardin 2020-03-17 09:43:02 -04:00 committed by GitHub
commit 8116b9c493
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 226 additions and 236 deletions

View File

@ -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.
@ -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:

View File

@ -107,6 +107,7 @@ 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' {
@ -114,11 +115,11 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf
}
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.
@ -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())

View File

@ -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(),
)
}
@ -280,8 +282,8 @@ 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
@ -289,7 +291,7 @@ func marshalResources(resources map[string]*states.Resource, module addrs.Module
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 {

View File

@ -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{
@ -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{
@ -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{
@ -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{
@ -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{

View File

@ -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
}

View File

@ -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
}

View File

@ -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{
@ -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

View File

@ -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
@ -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)
}
}
}

View File

@ -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

View File

@ -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.
@ -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 {

View File

@ -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))
}
}

View File

@ -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): {

View File

@ -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 {

View File

@ -246,40 +246,48 @@ func (s *SyncState) RemoveResourceIfEmpty(addr addrs.AbsResource) bool {
// The state is modified in-place if necessary, moving a resource instance
// between the two addresses. The return value is true if a change was made,
// and false otherwise.
func (s *SyncState) MaybeFixUpResourceInstanceAddressForCount(addr addrs.AbsResource, countEnabled bool) bool {
func (s *SyncState) MaybeFixUpResourceInstanceAddressForCount(addr addrs.ConfigResource, countEnabled bool) bool {
s.lock.Lock()
defer s.lock.Unlock()
ms := s.state.Module(addr.Module)
if ms == nil {
// get all modules instances that may match this state
modules := s.state.ModuleInstances(addr.Module)
if len(modules) == 0 {
return false
}
relAddr := addr.Resource
rs := ms.Resource(relAddr)
if rs == nil {
return false
}
huntKey := addrs.NoKey
replaceKey := addrs.InstanceKey(addrs.IntKey(0))
if !countEnabled {
huntKey, replaceKey = replaceKey, huntKey
changed := false
for _, ms := range modules {
relAddr := addr.Resource
rs := ms.Resource(relAddr)
if rs == nil {
continue
}
huntKey := addrs.NoKey
replaceKey := addrs.InstanceKey(addrs.IntKey(0))
if !countEnabled {
huntKey, replaceKey = replaceKey, huntKey
}
is, exists := rs.Instances[huntKey]
if !exists {
continue
}
if _, exists := rs.Instances[replaceKey]; exists {
// If the replacement key also exists then we'll do nothing and keep both.
continue
}
// If we get here then we need to "rename" from hunt to replace
rs.Instances[replaceKey] = is
delete(rs.Instances, huntKey)
changed = true
}
is, exists := rs.Instances[huntKey]
if !exists {
return false
}
if _, exists := rs.Instances[replaceKey]; exists {
// If the replacement key also exists then we'll do nothing and keep both.
return false
}
// If we get here then we need to "rename" from hunt to replace
rs.Instances[replaceKey] = is
delete(rs.Instances, huntKey)
return true
return changed
}
// SetResourceInstanceCurrent saves the given instance object as the current
@ -464,7 +472,7 @@ func (s *SyncState) RemovePlannedResourceInstanceObjects() {
moduleAddr := ms.Addr
for _, rs := range ms.Resources {
resAddr := rs.Addr
resAddr := rs.Addr.Resource
for ik, is := range rs.Instances {
instAddr := resAddr.Instance(ik)

View File

@ -1422,7 +1422,7 @@ func TestContext2Refresh_vars(t *testing.T) {
}
for _, r := range mod.Resources {
if r.Addr.Type == "" {
if r.Addr.Resource.Type == "" {
t.Fatalf("no type: %#v", r)
}
}

View File

@ -111,7 +111,7 @@ func evaluateResourceCountExpressionKnown(expr hcl.Expression, ctx EvalContext)
// Since the state is modified in-place, this function must take a writer lock
// on the state. The caller must therefore not also be holding a state lock,
// or this function will block forever awaiting the lock.
func fixResourceCountSetTransition(ctx EvalContext, addr addrs.AbsResource, countEnabled bool) {
func fixResourceCountSetTransition(ctx EvalContext, addr addrs.ConfigResource, countEnabled bool) {
state := ctx.State()
changed := state.MaybeFixUpResourceInstanceAddressForCount(addr, countEnabled)
if changed {

View File

@ -63,14 +63,13 @@ func (n *EvalCountFixZeroOneBoundaryGlobal) fixModule(ctx EvalContext, moduleAdd
}
for _, r := range ms.Resources {
addr := r.Addr.Absolute(moduleAddr)
rCfg := cfg.Module.ResourceByAddr(r.Addr)
rCfg := cfg.Module.ResourceByAddr(r.Addr.Resource)
if rCfg == nil {
log.Printf("[WARN] Not fixing up EachModes for %s because it has no config", addr)
log.Printf("[WARN] Not fixing up EachModes for %s because it has no config", r.Addr)
continue
}
hasCount := rCfg.Count != nil
fixResourceCountSetTransition(ctx, addr, hasCount)
fixResourceCountSetTransition(ctx, r.Addr.Config(), hasCount)
}
return nil

View File

@ -19,7 +19,7 @@ var (
_ GraphNodeDynamicExpandable = (*NodeRefreshableDataResource)(nil)
_ GraphNodeReferenceable = (*NodeRefreshableDataResource)(nil)
_ GraphNodeReferencer = (*NodeRefreshableDataResource)(nil)
_ GraphNodeResource = (*NodeRefreshableDataResource)(nil)
_ GraphNodeConfigResource = (*NodeRefreshableDataResource)(nil)
_ GraphNodeAttachResourceConfig = (*NodeRefreshableDataResource)(nil)
_ GraphNodeAttachProviderMetaConfigs = (*NodeAbstractResource)(nil)
)

View File

@ -16,11 +16,11 @@ import (
// abstract resource to a concrete one of some type.
type ConcreteResourceNodeFunc func(*NodeAbstractResource) dag.Vertex
// GraphNodeResource is implemented by any nodes that represent a resource.
// GraphNodeConfigResource is implemented by any nodes that represent a resource.
// The type of operation cannot be assumed, only that this node represents
// the given resource.
type GraphNodeResource interface {
ResourceAddr() addrs.AbsResource
type GraphNodeConfigResource interface {
ResourceAddr() addrs.ConfigResource
}
// ConcreteResourceInstanceNodeFunc is a callback type used to convert an
@ -69,7 +69,7 @@ var (
_ GraphNodeReferencer = (*NodeAbstractResource)(nil)
_ GraphNodeProviderConsumer = (*NodeAbstractResource)(nil)
_ GraphNodeProvisionerConsumer = (*NodeAbstractResource)(nil)
_ GraphNodeResource = (*NodeAbstractResource)(nil)
_ GraphNodeConfigResource = (*NodeAbstractResource)(nil)
_ GraphNodeAttachResourceConfig = (*NodeAbstractResource)(nil)
_ GraphNodeAttachResourceSchema = (*NodeAbstractResource)(nil)
_ GraphNodeAttachProvisionerSchema = (*NodeAbstractResource)(nil)
@ -117,7 +117,7 @@ var (
_ GraphNodeReferencer = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeProviderConsumer = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeProvisionerConsumer = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeResource = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeConfigResource = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeAttachResourceState = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeAttachResourceConfig = (*NodeAbstractResourceInstance)(nil)
@ -375,8 +375,8 @@ func (n *NodeAbstractResource) AttachProvisionerSchema(name string, schema *conf
}
// GraphNodeResource
func (n *NodeAbstractResource) ResourceAddr() addrs.AbsResource {
return n.addr()
func (n *NodeAbstractResource) ResourceAddr() addrs.ConfigResource {
return n.Addr
}
// GraphNodeResourceInstance
@ -384,11 +384,6 @@ func (n *NodeAbstractResourceInstance) ResourceInstanceAddr() addrs.AbsResourceI
return n.NodeAbstractResource.addr().Instance(n.InstanceKey)
}
// GraphNodeAddressable, TODO: remove, used by target, should unify
func (n *NodeAbstractResource) ResourceAddress() *ResourceAddress {
return NewLegacyResourceAddress(n.addr())
}
// GraphNodeTargetable
func (n *NodeAbstractResource) SetTargets(targets []addrs.Targetable) {
n.Targets = targets

View File

@ -21,7 +21,7 @@ type NodeApplyableResource struct {
}
var (
_ GraphNodeResource = (*NodeApplyableResource)(nil)
_ GraphNodeConfigResource = (*NodeApplyableResource)(nil)
_ GraphNodeEvalable = (*NodeApplyableResource)(nil)
_ GraphNodeProviderConsumer = (*NodeApplyableResource)(nil)
_ GraphNodeAttachResourceConfig = (*NodeApplyableResource)(nil)

View File

@ -28,7 +28,7 @@ type NodeApplyableResourceInstance struct {
}
var (
_ GraphNodeResource = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeConfigResource = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeCreator = (*NodeApplyableResourceInstance)(nil)
_ GraphNodeReferencer = (*NodeApplyableResourceInstance)(nil)
@ -99,8 +99,13 @@ func (n *NodeApplyableResourceInstance) References() []*addrs.Reference {
}
// GraphNodeAttachDependencies
func (n *NodeApplyableResourceInstance) AttachDependencies(deps []addrs.AbsResource) {
n.Dependencies = deps
func (n *NodeApplyableResourceInstance) AttachDependencies(deps []addrs.ConfigResource) {
var shimmed []addrs.AbsResource
for _, r := range deps {
shimmed = append(shimmed, r.Absolute(r.Module.UnkeyedInstanceShim()))
}
n.Dependencies = shimmed
}
// GraphNodeEvalable

View File

@ -26,7 +26,7 @@ type NodeDestroyResourceInstance struct {
}
var (
_ GraphNodeResource = (*NodeDestroyResourceInstance)(nil)
_ GraphNodeConfigResource = (*NodeDestroyResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodeDestroyResourceInstance)(nil)
_ GraphNodeDestroyer = (*NodeDestroyResourceInstance)(nil)
_ GraphNodeDestroyerCBD = (*NodeDestroyResourceInstance)(nil)
@ -292,10 +292,10 @@ type NodeDestroyResource struct {
}
var (
_ GraphNodeResource = (*NodeDestroyResource)(nil)
_ GraphNodeReferenceable = (*NodeDestroyResource)(nil)
_ GraphNodeReferencer = (*NodeDestroyResource)(nil)
_ GraphNodeEvalable = (*NodeDestroyResource)(nil)
_ GraphNodeConfigResource = (*NodeDestroyResource)(nil)
_ GraphNodeReferenceable = (*NodeDestroyResource)(nil)
_ GraphNodeReferencer = (*NodeDestroyResource)(nil)
_ GraphNodeEvalable = (*NodeDestroyResource)(nil)
// FIXME: this is here to document that this node is both
// GraphNodeProviderConsumer by virtue of the embedded
@ -339,7 +339,7 @@ func (n *NodeDestroyResource) EvalTree() EvalNode {
}
// GraphNodeResource
func (n *NodeDestroyResource) ResourceAddr() addrs.AbsResource {
func (n *NodeDestroyResource) ResourceAddr() addrs.ConfigResource {
return n.NodeAbstractResource.ResourceAddr()
}

View File

@ -33,7 +33,7 @@ type NodePlanDeposedResourceInstanceObject struct {
var (
_ GraphNodeDeposedResourceInstanceObject = (*NodePlanDeposedResourceInstanceObject)(nil)
_ GraphNodeResource = (*NodePlanDeposedResourceInstanceObject)(nil)
_ GraphNodeConfigResource = (*NodePlanDeposedResourceInstanceObject)(nil)
_ GraphNodeResourceInstance = (*NodePlanDeposedResourceInstanceObject)(nil)
_ GraphNodeReferenceable = (*NodePlanDeposedResourceInstanceObject)(nil)
_ GraphNodeReferencer = (*NodePlanDeposedResourceInstanceObject)(nil)
@ -167,7 +167,7 @@ type NodeDestroyDeposedResourceInstanceObject struct {
var (
_ GraphNodeDeposedResourceInstanceObject = (*NodeDestroyDeposedResourceInstanceObject)(nil)
_ GraphNodeResource = (*NodeDestroyDeposedResourceInstanceObject)(nil)
_ GraphNodeConfigResource = (*NodeDestroyDeposedResourceInstanceObject)(nil)
_ GraphNodeResourceInstance = (*NodeDestroyDeposedResourceInstanceObject)(nil)
_ GraphNodeDestroyer = (*NodeDestroyDeposedResourceInstanceObject)(nil)
_ GraphNodeDestroyerCBD = (*NodeDestroyDeposedResourceInstanceObject)(nil)

View File

@ -23,7 +23,7 @@ var (
_ GraphNodeDynamicExpandable = (*NodePlannableResource)(nil)
_ GraphNodeReferenceable = (*NodePlannableResource)(nil)
_ GraphNodeReferencer = (*NodePlannableResource)(nil)
_ GraphNodeResource = (*NodePlannableResource)(nil)
_ GraphNodeConfigResource = (*NodePlannableResource)(nil)
_ GraphNodeAttachResourceConfig = (*NodePlannableResource)(nil)
)

View File

@ -21,7 +21,7 @@ var (
_ GraphNodeReferenceable = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeReferencer = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeDestroyer = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeResource = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeConfigResource = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeAttachResourceConfig = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeAttachResourceState = (*NodePlanDestroyableResourceInstance)(nil)

View File

@ -23,7 +23,7 @@ var (
_ GraphNodeModuleInstance = (*NodePlannableResourceInstance)(nil)
_ GraphNodeReferenceable = (*NodePlannableResourceInstance)(nil)
_ GraphNodeReferencer = (*NodePlannableResourceInstance)(nil)
_ GraphNodeResource = (*NodePlannableResourceInstance)(nil)
_ GraphNodeConfigResource = (*NodePlannableResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodePlannableResourceInstance)(nil)
_ GraphNodeAttachResourceConfig = (*NodePlannableResourceInstance)(nil)
_ GraphNodeAttachResourceState = (*NodePlannableResourceInstance)(nil)

View File

@ -16,7 +16,7 @@ var (
_ GraphNodeModuleInstance = (*NodePlannableResourceInstanceOrphan)(nil)
_ GraphNodeReferenceable = (*NodePlannableResourceInstanceOrphan)(nil)
_ GraphNodeReferencer = (*NodePlannableResourceInstanceOrphan)(nil)
_ GraphNodeResource = (*NodePlannableResourceInstanceOrphan)(nil)
_ GraphNodeConfigResource = (*NodePlannableResourceInstanceOrphan)(nil)
_ GraphNodeResourceInstance = (*NodePlannableResourceInstanceOrphan)(nil)
_ GraphNodeAttachResourceConfig = (*NodePlannableResourceInstanceOrphan)(nil)
_ GraphNodeAttachResourceState = (*NodePlannableResourceInstanceOrphan)(nil)

View File

@ -28,14 +28,19 @@ var (
_ GraphNodeDynamicExpandable = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeReferenceable = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeReferencer = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeResource = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeConfigResource = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeAttachResourceConfig = (*NodeRefreshableManagedResource)(nil)
_ GraphNodeAttachDependencies = (*NodeRefreshableManagedResource)(nil)
)
// GraphNodeAttachDependencies
func (n *NodeRefreshableManagedResource) AttachDependencies(deps []addrs.AbsResource) {
n.Dependencies = deps
func (n *NodeRefreshableManagedResource) AttachDependencies(deps []addrs.ConfigResource) {
var shimmed []addrs.AbsResource
for _, r := range deps {
shimmed = append(shimmed, r.Absolute(r.Module.UnkeyedInstanceShim()))
}
n.Dependencies = shimmed
}
// GraphNodeDynamicExpandable
@ -144,7 +149,7 @@ var (
_ GraphNodeReferenceable = (*NodeRefreshableManagedResourceInstance)(nil)
_ GraphNodeReferencer = (*NodeRefreshableManagedResourceInstance)(nil)
_ GraphNodeDestroyer = (*NodeRefreshableManagedResourceInstance)(nil)
_ GraphNodeResource = (*NodeRefreshableManagedResourceInstance)(nil)
_ GraphNodeConfigResource = (*NodeRefreshableManagedResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodeRefreshableManagedResourceInstance)(nil)
_ GraphNodeAttachResourceConfig = (*NodeRefreshableManagedResourceInstance)(nil)
_ GraphNodeAttachResourceState = (*NodeRefreshableManagedResourceInstance)(nil)

View File

@ -18,7 +18,7 @@ var (
_ GraphNodeEvalable = (*NodeValidatableResource)(nil)
_ GraphNodeReferenceable = (*NodeValidatableResource)(nil)
_ GraphNodeReferencer = (*NodeValidatableResource)(nil)
_ GraphNodeResource = (*NodeValidatableResource)(nil)
_ GraphNodeConfigResource = (*NodeValidatableResource)(nil)
_ GraphNodeAttachResourceConfig = (*NodeValidatableResource)(nil)
_ GraphNodeAttachProviderMetaConfigs = (*NodeValidatableResource)(nil)
)

View File

@ -3,7 +3,6 @@ package terraform
import (
"fmt"
"reflect"
"strconv"
"testing"
"github.com/hashicorp/terraform/configs/configschema"
@ -13,63 +12,6 @@ import (
"github.com/mitchellh/reflectwalk"
)
func TestInstanceInfoResourceAddress(t *testing.T) {
tests := []struct {
Input *InstanceInfo
Want string
}{
{
&InstanceInfo{
Id: "test_resource.baz",
},
"test_resource.baz",
},
{
&InstanceInfo{
Id: "test_resource.baz",
ModulePath: rootModulePath,
},
"test_resource.baz",
},
{
&InstanceInfo{
Id: "test_resource.baz",
ModulePath: []string{"root", "foo"},
},
"module.foo.test_resource.baz",
},
{
&InstanceInfo{
Id: "test_resource.baz",
ModulePath: []string{"root", "foo", "bar"},
},
"module.foo.module.bar.test_resource.baz",
},
{
&InstanceInfo{
Id: "test_resource.baz (tainted)",
},
"test_resource.baz.tainted",
},
{
&InstanceInfo{
Id: "test_resource.baz (deposed #0)",
},
"test_resource.baz.deposed",
},
}
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
gotAddr := test.Input.ResourceAddress()
got := gotAddr.String()
if got != test.Want {
t.Fatalf("wrong result\ngot: %s\nwant: %s", got, test.Want)
}
})
}
}
func TestResourceConfigGet(t *testing.T) {
fooStringSchema := &configschema.Block{
Attributes: map[string]*configschema.Attribute{

View File

@ -8,7 +8,7 @@ import (
// GraphNodeAttachProviderMetaConfigs is an interface that must be implemented
// by nodes that want provider meta configurations attached.
type GraphNodeAttachProviderMetaConfigs interface {
GraphNodeResource
GraphNodeConfigResource
// Sets the configuration
AttachProviderMetaConfigs(map[addrs.Provider]*configs.ProviderMeta)

View File

@ -10,7 +10,7 @@ import (
// GraphNodeAttachResourceConfig is an interface that must be implemented by nodes
// that want resource configurations attached.
type GraphNodeAttachResourceConfig interface {
GraphNodeResource
GraphNodeConfigResource
// Sets the configuration
AttachResourceConfig(*configs.Resource)
@ -40,7 +40,7 @@ func (t *AttachResourceConfigTransformer) Transform(g *Graph) error {
addr := arn.ResourceAddr()
// Get the configuration.
config := t.Config.DescendentForInstance(addr.Module)
config := t.Config.Descendent(addr.Module)
if config == nil {
log.Printf("[TRACE] AttachResourceConfigTransformer: %q (%T) has no configuration available", dag.VertexName(v), v)
continue

View File

@ -13,7 +13,7 @@ import (
// GraphNodeAttachResourceSchema is an interface implemented by node types
// that need a resource schema attached.
type GraphNodeAttachResourceSchema interface {
GraphNodeResource
GraphNodeConfigResource
GraphNodeProviderConsumer
AttachResourceSchema(schema *configschema.Block, version uint64)

View File

@ -36,9 +36,9 @@ func (t *DiffTransformer) Transform(g *Graph) error {
// get evaluated before any of the corresponding instances by creating
// dependency edges, so we'll do some prep work here to ensure we'll only
// create connections to nodes that existed before we started here.
resourceNodes := map[string][]GraphNodeResource{}
resourceNodes := map[string][]GraphNodeConfigResource{}
for _, node := range g.Vertices() {
rn, ok := node.(GraphNodeResource)
rn, ok := node.(GraphNodeConfigResource)
if !ok {
continue
}

View File

@ -18,44 +18,39 @@ import (
type OrphanResourceCountTransformer struct {
Concrete ConcreteResourceInstanceNodeFunc
Addr addrs.AbsResource // Addr of the resource to look for orphans
Addr addrs.ConfigResource // Addr of the resource to look for orphans
InstanceAddrs []addrs.AbsResourceInstance // Addresses that currently exist in config
State *states.State // Full global state
}
func (t *OrphanResourceCountTransformer) Transform(g *Graph) error {
// FIXME: This is currently assuming that all of the instances of
// this resource belong to a single module instance, which is true
// at the time of writing this because Terraform Core doesn't support
// repetition of module calls yet, but this will need to be corrected
// in order to support count and for_each on module calls, where
// our t.InstanceAddrs may contain resource instances from many different
// module instances.
rs := t.State.Resource(t.Addr)
if rs == nil {
resources := t.State.Resources(t.Addr)
if len(resources) == 0 {
return nil // Resource doesn't exist in state, so nothing to do!
}
// This is an O(n*m) analysis, which we accept for now because the
// number of instances of a single resource ought to always be small in any
// reasonable Terraform configuration.
Have:
for key := range rs.Instances {
thisAddr := t.Addr.Instance(key)
for _, wantAddr := range t.InstanceAddrs {
if wantAddr.Equal(thisAddr) {
continue Have
for _, rs := range resources {
// This is an O(n*m) analysis, which we accept for now because the
// number of instances of a single resource ought to always be small in any
// reasonable Terraform configuration.
Have:
for key := range rs.Instances {
thisAddr := rs.Addr.Instance(key)
for _, wantAddr := range t.InstanceAddrs {
if wantAddr.Equal(thisAddr) {
continue Have
}
}
}
// If thisAddr is not in t.InstanceAddrs then we've found an "orphan"
// If thisAddr is not in t.InstanceAddrs then we've found an "orphan"
abstract := NewNodeAbstractResourceInstance(thisAddr)
var node dag.Vertex = abstract
if f := t.Concrete; f != nil {
node = f(abstract)
abstract := NewNodeAbstractResourceInstance(thisAddr)
var node dag.Vertex = abstract
if f := t.Concrete; f != nil {
node = f(abstract)
}
log.Printf("[TRACE] OrphanResourceCountTransformer: adding %s as %T", thisAddr, node)
g.Add(node)
}
log.Printf("[TRACE] OrphanResourceCountTransformer: adding %s as %T", thisAddr, node)
g.Add(node)
}
return nil

View File

@ -74,13 +74,13 @@ func (t *OrphanResourceInstanceTransformer) transform(g *Graph, ms *states.Modul
// pseudo-arguments here. They are handled by OrphanResourceCountTransformer.
for _, rs := range ms.Resources {
if m != nil {
if r := m.ResourceByAddr(rs.Addr); r != nil {
if r := m.ResourceByAddr(rs.Addr.Resource); r != nil {
continue
}
}
for key := range rs.Instances {
addr := rs.Addr.Instance(key).Absolute(moduleAddr)
addr := rs.Addr.Instance(key)
abstract := NewNodeAbstractResourceInstance(addr)
var node dag.Vertex = abstract
if f := t.Concrete; f != nil {
@ -137,7 +137,7 @@ func (t *OrphanResourceTransformer) Transform(g *Graph) error {
case GraphNodeResourceInstance:
k := tv.ResourceInstanceAddr().ContainingResource().String()
deps[k] = append(deps[k], v)
case GraphNodeResource:
case GraphNodeConfigResource:
k := tv.ResourceAddr().String()
deps[k] = append(deps[k], v)
case GraphNodeDestroyer:
@ -153,13 +153,13 @@ func (t *OrphanResourceTransformer) Transform(g *Graph) error {
for _, rs := range ms.Resources {
if mc != nil {
if r := mc.Module.ResourceByAddr(rs.Addr); r != nil {
if r := mc.Module.ResourceByAddr(rs.Addr.Resource); r != nil {
// It's in the config, so nothing to do for this one.
continue
}
}
addr := rs.Addr.Absolute(moduleAddr)
addr := rs.Addr
abstract := NewNodeAbstractResource(addr)
var node dag.Vertex = abstract
if f := t.Concrete; f != nil {

View File

@ -41,8 +41,8 @@ type GraphNodeReferencer interface {
}
type GraphNodeAttachDependencies interface {
GraphNodeResource
AttachDependencies([]addrs.AbsResource)
GraphNodeConfigResource
AttachDependencies([]addrs.ConfigResource)
}
// GraphNodeReferenceOutside is an interface that can optionally be implemented.
@ -116,6 +116,8 @@ type AttachDependenciesTransformer struct {
}
func (t AttachDependenciesTransformer) Transform(g *Graph) error {
// FIXME: this is only working with ResourceConfigAddr for now
for _, v := range g.Vertices() {
attacher, ok := v.(GraphNodeAttachDependencies)
if !ok {
@ -135,15 +137,15 @@ func (t AttachDependenciesTransformer) Transform(g *Graph) error {
// dedupe addrs when there's multiple instances involved, or
// multiple paths in the un-reduced graph
depMap := map[string]addrs.AbsResource{}
depMap := map[string]addrs.ConfigResource{}
for _, d := range ans {
var addr addrs.AbsResource
var addr addrs.ConfigResource
switch d := d.(type) {
case GraphNodeResourceInstance:
instAddr := d.ResourceInstanceAddr()
addr = instAddr.Resource.Resource.Absolute(instAddr.Module)
case GraphNodeResource:
addr = instAddr.ContainingResource().Config()
case GraphNodeConfigResource:
addr = d.ResourceAddr()
default:
continue
@ -160,7 +162,7 @@ func (t AttachDependenciesTransformer) Transform(g *Graph) error {
depMap[addr.String()] = addr
}
deps := make([]addrs.AbsResource, 0, len(depMap))
deps := make([]addrs.ConfigResource, 0, len(depMap))
for _, d := range depMap {
deps = append(deps, d)
}

View File

@ -16,7 +16,7 @@ type ResourceCountTransformer struct {
Concrete ConcreteResourceInstanceNodeFunc
Schema *configschema.Block
Addr addrs.AbsResource
Addr addrs.ConfigResource
InstanceAddrs []addrs.AbsResourceInstance
}

View File

@ -43,10 +43,8 @@ func (t *StateTransformer) Transform(g *Graph) error {
}
for _, ms := range t.State.Modules {
moduleAddr := ms.Addr
for _, rs := range ms.Resources {
resourceAddr := rs.Addr.Absolute(moduleAddr)
resourceAddr := rs.Addr
for key, is := range rs.Instances {
addr := resourceAddr.Instance(key)

View File

@ -58,7 +58,7 @@ func (t *TargetsTransformer) Transform(g *Graph) error {
for _, v := range g.Vertices() {
removable := false
if _, ok := v.(GraphNodeResource); ok {
if _, ok := v.(GraphNodeConfigResource); ok {
removable = true
}
@ -225,16 +225,12 @@ func (t *TargetsTransformer) nodeIsTarget(v dag.Vertex, targets []addrs.Targetab
switch r := v.(type) {
case GraphNodeResourceInstance:
vertexAddr = r.ResourceInstanceAddr()
case GraphNodeResource:
case GraphNodeConfigResource:
vertexAddr = r.ResourceAddr()
default:
// Only resource and resource instance nodes can be targeted.
return false
}
_, ok := v.(GraphNodeResource)
if !ok {
return false
}
for _, targetAddr := range targets {
if t.IgnoreIndices {