core: schema attach interfaces are not mutually-exclusive

It was incorrect to use a type switch to detect the optional schema
attachment interfaces, because they are not mutually-exclusive: resource
nodes implement both GraphNodeAttachResourceSchema and
GraphNodeAttachProvisionerSchema.

This fixes a number of test regressions around dependency analysis in
"provisioner" blocks.
This commit is contained in:
Martin Atkins 2018-05-31 17:14:20 -07:00
parent 4b085c9cac
commit 1761faa29c
2 changed files with 37 additions and 33 deletions

View File

@ -7,13 +7,11 @@ import (
"github.com/hashicorp/hcl2/hcl" "github.com/hashicorp/hcl2/hcl"
"github.com/hashicorp/hcl2/hcl/hclsyntax" "github.com/hashicorp/hcl2/hcl/hclsyntax"
"github.com/hashicorp/terraform/config/configschema"
"github.com/hashicorp/terraform/lang"
"github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/config/configschema"
"github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/configs"
"github.com/hashicorp/terraform/dag" "github.com/hashicorp/terraform/dag"
"github.com/hashicorp/terraform/lang"
) )
// ConcreteResourceNodeFunc is a callback type used to convert an // ConcreteResourceNodeFunc is a callback type used to convert an
@ -61,16 +59,17 @@ type NodeAbstractResource struct {
} }
var ( var (
_ GraphNodeSubPath = (*NodeAbstractResource)(nil) _ GraphNodeSubPath = (*NodeAbstractResource)(nil)
_ GraphNodeReferenceable = (*NodeAbstractResource)(nil) _ GraphNodeReferenceable = (*NodeAbstractResource)(nil)
_ GraphNodeReferencer = (*NodeAbstractResource)(nil) _ GraphNodeReferencer = (*NodeAbstractResource)(nil)
_ GraphNodeProviderConsumer = (*NodeAbstractResource)(nil) _ GraphNodeProviderConsumer = (*NodeAbstractResource)(nil)
_ GraphNodeProvisionerConsumer = (*NodeAbstractResource)(nil) _ GraphNodeProvisionerConsumer = (*NodeAbstractResource)(nil)
_ GraphNodeResource = (*NodeAbstractResource)(nil) _ GraphNodeResource = (*NodeAbstractResource)(nil)
_ GraphNodeAttachResourceConfig = (*NodeAbstractResource)(nil) _ GraphNodeAttachResourceConfig = (*NodeAbstractResource)(nil)
_ GraphNodeAttachResourceSchema = (*NodeAbstractResource)(nil) _ GraphNodeAttachResourceSchema = (*NodeAbstractResource)(nil)
_ GraphNodeTargetable = (*NodeAbstractResource)(nil) _ GraphNodeAttachProvisionerSchema = (*NodeAbstractResource)(nil)
_ dag.GraphNodeDotter = (*NodeAbstractResource)(nil) _ GraphNodeTargetable = (*NodeAbstractResource)(nil)
_ dag.GraphNodeDotter = (*NodeAbstractResource)(nil)
) )
// NewNodeAbstractResource creates an abstract resource graph node for // NewNodeAbstractResource creates an abstract resource graph node for
@ -98,18 +97,19 @@ type NodeAbstractResourceInstance struct {
} }
var ( var (
_ GraphNodeSubPath = (*NodeAbstractResourceInstance)(nil) _ GraphNodeSubPath = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeReferenceable = (*NodeAbstractResourceInstance)(nil) _ GraphNodeReferenceable = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeReferencer = (*NodeAbstractResourceInstance)(nil) _ GraphNodeReferencer = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeProviderConsumer = (*NodeAbstractResourceInstance)(nil) _ GraphNodeProviderConsumer = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeProvisionerConsumer = (*NodeAbstractResourceInstance)(nil) _ GraphNodeProvisionerConsumer = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeResource = (*NodeAbstractResourceInstance)(nil) _ GraphNodeResource = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodeAbstractResourceInstance)(nil) _ GraphNodeResourceInstance = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeAttachResourceState = (*NodeAbstractResourceInstance)(nil) _ GraphNodeAttachResourceState = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeAttachResourceConfig = (*NodeAbstractResourceInstance)(nil) _ GraphNodeAttachResourceConfig = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeAttachResourceSchema = (*NodeAbstractResourceInstance)(nil) _ GraphNodeAttachResourceSchema = (*NodeAbstractResourceInstance)(nil)
_ GraphNodeTargetable = (*NodeAbstractResourceInstance)(nil) _ GraphNodeAttachProvisionerSchema = (*NodeAbstractResourceInstance)(nil)
_ dag.GraphNodeDotter = (*NodeAbstractResourceInstance)(nil) _ GraphNodeTargetable = (*NodeAbstractResourceInstance)(nil)
_ dag.GraphNodeDotter = (*NodeAbstractResourceInstance)(nil)
) )
// NewNodeAbstractResourceInstance creates an abstract resource instance graph // NewNodeAbstractResourceInstance creates an abstract resource instance graph

View File

@ -54,8 +54,8 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error {
} }
for _, v := range g.Vertices() { for _, v := range g.Vertices() {
switch tv := v.(type) {
case GraphNodeAttachResourceSchema: if tv, ok := v.(GraphNodeAttachResourceSchema); ok {
addr := tv.ResourceAddr() addr := tv.ResourceAddr()
mode := addr.Resource.Mode mode := addr.Resource.Mode
typeName := addr.Resource.Type typeName := addr.Resource.Type
@ -75,16 +75,20 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error {
} }
log.Printf("[TRACE] AttachSchemaTransformer: attaching resource schema to %s", dag.VertexName(v)) log.Printf("[TRACE] AttachSchemaTransformer: attaching resource schema to %s", dag.VertexName(v))
tv.AttachResourceSchema(schema) tv.AttachResourceSchema(schema)
case GraphNodeAttachProviderConfigSchema: }
if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok {
providerAddr := tv.ProviderAddr() providerAddr := tv.ProviderAddr()
schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.Type) schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.Type)
if schema == nil { if schema == nil {
log.Printf("[ERROR] AttachSchemaTransformer: No schema available for %s", providerAddr) log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr)
continue continue
} }
log.Printf("[TRACE] AttachSchemaTransformer: attaching schema to %s", dag.VertexName(v)) log.Printf("[TRACE] AttachSchemaTransformer: attaching provider config schema to %s", dag.VertexName(v))
tv.AttachProviderConfigSchema(schema) tv.AttachProviderConfigSchema(schema)
case GraphNodeAttachProvisionerSchema: }
if tv, ok := v.(GraphNodeAttachProvisionerSchema); ok {
names := tv.ProvisionedBy() names := tv.ProvisionedBy()
for _, name := range names { for _, name := range names {
schema := t.Schemas.ProvisionerConfig(name) schema := t.Schemas.ProvisionerConfig(name)
@ -92,7 +96,7 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error {
log.Printf("[ERROR] AttachSchemaTransformer: No schema available for provisioner %q on %q", name, dag.VertexName(v)) log.Printf("[ERROR] AttachSchemaTransformer: No schema available for provisioner %q on %q", name, dag.VertexName(v))
continue continue
} }
log.Printf("[TRACE] AttachSchemaTransformer: attaching provisioner %q schema to %s", name, dag.VertexName(v)) log.Printf("[TRACE] AttachSchemaTransformer: attaching provisioner %q config schema to %s", name, dag.VertexName(v))
tv.AttachProvisionerSchema(name, schema) tv.AttachProvisionerSchema(name, schema)
} }
} }