From 38ec730b0e35c5ddd63d64690e123ef6d26371c3 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Tue, 31 Aug 2021 16:36:27 -0700 Subject: [PATCH] core: Opportunistic schema loading during graph construction Previously the graph builders all expected to be given a full manifest of all of the plugin component schemas that they could need during their analysis work. That made sense when terraform.NewContext would always proactively load all of the schemas before doing any other work, but we now have a load-as-needed strategy for schemas. We'll now have the graph builders use the contextPlugins object they each already hold to retrieve individual schemas when needed. This avoids the need to prepare a redundant data structure to pass alongside the contextPlugins object, and leans on the memoization behavior inside contextPlugins to preserve the old behavior of loading each provider's schema only once. --- internal/terraform/context_apply.go | 13 ++---- internal/terraform/context_eval.go | 1 - internal/terraform/context_import.go | 1 - internal/terraform/context_plan.go | 3 -- internal/terraform/context_plugins.go | 34 ++++++++++++++ internal/terraform/context_validate.go | 1 - internal/terraform/context_validate_test.go | 1 - internal/terraform/graph_builder_apply.go | 16 +++---- .../terraform/graph_builder_apply_test.go | 10 ----- .../terraform/graph_builder_destroy_plan.go | 9 +--- internal/terraform/graph_builder_eval.go | 6 +-- internal/terraform/graph_builder_import.go | 6 +-- internal/terraform/graph_builder_plan.go | 6 +-- internal/terraform/graph_builder_plan_test.go | 22 --------- internal/terraform/schemas_test.go | 45 +++++++++++++++++++ internal/terraform/transform_attach_schema.go | 22 ++++++--- internal/terraform/transform_destroy_cbd.go | 5 --- .../terraform/transform_destroy_cbd_test.go | 1 - internal/terraform/transform_destroy_edge.go | 5 --- .../terraform/transform_destroy_edge_test.go | 18 +++----- .../transform_transitive_reduction_test.go | 28 ++++++------ 21 files changed, 126 insertions(+), 127 deletions(-) diff --git a/internal/terraform/context_apply.go b/internal/terraform/context_apply.go index 4d5dc890f..ff32074ec 100644 --- a/internal/terraform/context_apply.go +++ b/internal/terraform/context_apply.go @@ -32,7 +32,7 @@ func (c *Context) Apply(plan *plans.Plan, config *configs.Config) (*states.State log.Printf("[DEBUG] Building and walking apply graph for %s plan", plan.UIMode) - graph, operation, moreDiags := c.applyGraph(plan, config, schemas, true) + graph, operation, moreDiags := c.applyGraph(plan, config, true) if moreDiags.HasErrors() { return nil, diags } @@ -90,13 +90,12 @@ Note that the -target option is not suitable for routine use, and is provided on return newState, diags } -func (c *Context) applyGraph(plan *plans.Plan, config *configs.Config, schemas *Schemas, validate bool) (*Graph, walkOperation, tfdiags.Diagnostics) { +func (c *Context) applyGraph(plan *plans.Plan, config *configs.Config, validate bool) (*Graph, walkOperation, tfdiags.Diagnostics) { graph, diags := (&ApplyGraphBuilder{ Config: config, Changes: plan.Changes, State: plan.PriorState, Plugins: c.plugins, - Schemas: schemas, Targets: plan.TargetAddrs, ForceReplace: plan.ForceReplaceAddrs, Validate: validate, @@ -130,13 +129,7 @@ func (c *Context) ApplyGraphForUI(plan *plans.Plan, config *configs.Config) (*Gr var diags tfdiags.Diagnostics - schemas, moreDiags := c.Schemas(config, plan.PriorState) - diags = diags.Append(moreDiags) - if diags.HasErrors() { - return nil, diags - } - - graph, _, moreDiags := c.applyGraph(plan, config, schemas, false) + graph, _, moreDiags := c.applyGraph(plan, config, false) diags = diags.Append(moreDiags) return graph, diags } diff --git a/internal/terraform/context_eval.go b/internal/terraform/context_eval.go index ad3deeee1..8201db4d6 100644 --- a/internal/terraform/context_eval.go +++ b/internal/terraform/context_eval.go @@ -69,7 +69,6 @@ func (c *Context) Eval(config *configs.Config, state *states.State, moduleAddr a Config: config, State: state, Plugins: c.plugins, - Schemas: schemas, }).Build(addrs.RootModuleInstance) diags = diags.Append(moreDiags) if moreDiags.HasErrors() { diff --git a/internal/terraform/context_import.go b/internal/terraform/context_import.go index 8675e06b5..f4bc6d809 100644 --- a/internal/terraform/context_import.go +++ b/internal/terraform/context_import.go @@ -64,7 +64,6 @@ func (c *Context) Import(config *configs.Config, prevRunState *states.State, opt ImportTargets: opts.Targets, Config: config, Plugins: c.plugins, - Schemas: schemas, } // Build the graph diff --git a/internal/terraform/context_plan.go b/internal/terraform/context_plan.go index 9f9170c8a..208ee771c 100644 --- a/internal/terraform/context_plan.go +++ b/internal/terraform/context_plan.go @@ -372,7 +372,6 @@ func (c *Context) planGraph(config *configs.Config, prevRunState *states.State, Config: config, State: prevRunState, Plugins: c.plugins, - Schemas: schemas, Targets: opts.Targets, ForceReplace: opts.ForceReplace, Validate: validate, @@ -384,7 +383,6 @@ func (c *Context) planGraph(config *configs.Config, prevRunState *states.State, Config: config, State: prevRunState, Plugins: c.plugins, - Schemas: schemas, Targets: opts.Targets, Validate: validate, skipRefresh: opts.SkipRefresh, @@ -396,7 +394,6 @@ func (c *Context) planGraph(config *configs.Config, prevRunState *states.State, Config: config, State: prevRunState, Plugins: c.plugins, - Schemas: schemas, Targets: opts.Targets, Validate: validate, skipRefresh: opts.SkipRefresh, diff --git a/internal/terraform/context_plugins.go b/internal/terraform/context_plugins.go index 5711badbd..4fbdf84d0 100644 --- a/internal/terraform/context_plugins.go +++ b/internal/terraform/context_plugins.go @@ -134,6 +134,40 @@ func (cp *contextPlugins) ProviderSchema(addr addrs.Provider) (*ProviderSchema, return s, nil } +// ProviderConfigSchema is a helper wrapper around ProviderSchema which first +// reads the full schema of the given provider and then extracts just the +// provider's configuration schema, which defines what's expected in a +// "provider" block in the configuration when configuring this provider. +func (cp *contextPlugins) ProviderConfigSchema(providerAddr addrs.Provider) (*configschema.Block, error) { + providerSchema, err := cp.ProviderSchema(providerAddr) + if err != nil { + return nil, err + } + + return providerSchema.Provider, nil +} + +// ResourceTypeSchema is a helper wrapper around ProviderSchema which first +// reads the schema of the given provider and then tries to find the schema +// for the resource type of the given resource mode in that provider. +// +// ResourceTypeSchema will return an error if the provider schema lookup +// fails, but will return nil if the provider schema lookup succeeds but then +// the provider doesn't have a resource of the requested type. +// +// Managed resource types have versioned schemas, so the second return value +// is the current schema version number for the requested resource. The version +// is irrelevant for other resource modes. +func (cp *contextPlugins) ResourceTypeSchema(providerAddr addrs.Provider, resourceMode addrs.ResourceMode, resourceType string) (*configschema.Block, uint64, error) { + providerSchema, err := cp.ProviderSchema(providerAddr) + if err != nil { + return nil, 0, err + } + + schema, version := providerSchema.SchemaForResourceType(resourceMode, resourceType) + return schema, version, nil +} + // ProvisionerSchema uses a temporary instance of the provisioner with the // given type name to obtain the schema for that provisioner's configuration. // diff --git a/internal/terraform/context_validate.go b/internal/terraform/context_validate.go index f95127895..f5aa8540c 100644 --- a/internal/terraform/context_validate.go +++ b/internal/terraform/context_validate.go @@ -46,7 +46,6 @@ func (c *Context) Validate(config *configs.Config) tfdiags.Diagnostics { graph, moreDiags := ValidateGraphBuilder(&PlanGraphBuilder{ Config: config, Plugins: c.plugins, - Schemas: schemas, Validate: true, State: states.NewState(), }).Build(addrs.RootModuleInstance) diff --git a/internal/terraform/context_validate_test.go b/internal/terraform/context_validate_test.go index e4eee13b4..0c5a2a3a5 100644 --- a/internal/terraform/context_validate_test.go +++ b/internal/terraform/context_validate_test.go @@ -1201,7 +1201,6 @@ func TestContext2Validate_PlanGraphBuilder(t *testing.T) { Config: fixture.Config, State: states.NewState(), Plugins: c.plugins, - Schemas: schemas, }).Build(addrs.RootModuleInstance) if diags.HasErrors() { t.Fatalf("errors from PlanGraphBuilder: %s", diags.Err()) diff --git a/internal/terraform/graph_builder_apply.go b/internal/terraform/graph_builder_apply.go index ca8e5777f..94f1e7699 100644 --- a/internal/terraform/graph_builder_apply.go +++ b/internal/terraform/graph_builder_apply.go @@ -30,10 +30,6 @@ type ApplyGraphBuilder struct { // provisioners) available for use. Plugins *contextPlugins - // Schemas is the repository of schemas we will draw from to analyse - // the configuration. - Schemas *Schemas - // Targets are resources to target. This is only required to make sure // unnecessary outputs aren't included in the apply graph. The plan // builder successfully handles targeting resources. In the future, @@ -123,7 +119,7 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer { // Must attach schemas before ReferenceTransformer so that we can // analyze the configuration to find references. - &AttachSchemaTransformer{Schemas: b.Schemas, Config: b.Config}, + &AttachSchemaTransformer{Plugins: b.Plugins, Config: b.Config}, // Create expansion nodes for all of the module calls. This must // come after all other transformers that create nodes representing @@ -140,14 +136,12 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer { // Destruction ordering &DestroyEdgeTransformer{ - Config: b.Config, - State: b.State, - Schemas: b.Schemas, + Config: b.Config, + State: b.State, }, &CBDEdgeTransformer{ - Config: b.Config, - State: b.State, - Schemas: b.Schemas, + Config: b.Config, + State: b.State, }, // We need to remove configuration nodes that are not used at all, as diff --git a/internal/terraform/graph_builder_apply_test.go b/internal/terraform/graph_builder_apply_test.go index 9aaa1650d..e1aba8d2c 100644 --- a/internal/terraform/graph_builder_apply_test.go +++ b/internal/terraform/graph_builder_apply_test.go @@ -49,7 +49,6 @@ func TestApplyGraphBuilder(t *testing.T) { Config: testModule(t, "graph-builder-apply-basic"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), } g, err := b.Build(addrs.RootModuleInstance) @@ -113,7 +112,6 @@ func TestApplyGraphBuilder_depCbd(t *testing.T) { Config: testModule(t, "graph-builder-apply-dep-cbd"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), State: state, } @@ -187,7 +185,6 @@ func TestApplyGraphBuilder_doubleCBD(t *testing.T) { Config: testModule(t, "graph-builder-apply-double-cbd"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), } g, err := b.Build(addrs.RootModuleInstance) @@ -282,7 +279,6 @@ func TestApplyGraphBuilder_destroyStateOnly(t *testing.T) { Changes: changes, State: state, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), } g, diags := b.Build(addrs.RootModuleInstance) @@ -344,7 +340,6 @@ func TestApplyGraphBuilder_destroyCount(t *testing.T) { Config: testModule(t, "graph-builder-apply-count"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), State: state, } @@ -407,7 +402,6 @@ func TestApplyGraphBuilder_moduleDestroy(t *testing.T) { Config: testModule(t, "graph-builder-apply-module-destroy"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), State: state, } @@ -445,7 +439,6 @@ func TestApplyGraphBuilder_targetModule(t *testing.T) { Config: testModule(t, "graph-builder-apply-target-module"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), Targets: []addrs.Targetable{ addrs.RootModuleInstance.Child("child2", addrs.NoKey), }, @@ -542,7 +535,6 @@ func TestApplyGraphBuilder_updateFromOrphan(t *testing.T) { Config: testModule(t, "graph-builder-apply-orphan-update"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: schemas, State: state, } @@ -643,7 +635,6 @@ func TestApplyGraphBuilder_updateFromCBDOrphan(t *testing.T) { Config: testModule(t, "graph-builder-apply-orphan-update"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: schemas, State: state, } @@ -694,7 +685,6 @@ func TestApplyGraphBuilder_orphanedWithProvider(t *testing.T) { Config: testModule(t, "graph-builder-orphan-alias"), Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), State: state, } diff --git a/internal/terraform/graph_builder_destroy_plan.go b/internal/terraform/graph_builder_destroy_plan.go index 55bae82fd..0bac6305e 100644 --- a/internal/terraform/graph_builder_destroy_plan.go +++ b/internal/terraform/graph_builder_destroy_plan.go @@ -27,10 +27,6 @@ type DestroyPlanGraphBuilder struct { // provisioners) available for use. Plugins *contextPlugins - // Schemas is the repository of schemas we will draw from to analyse - // the configuration. - Schemas *Schemas - // Targets are resources to target Targets []addrs.Targetable @@ -99,9 +95,8 @@ func (b *DestroyPlanGraphBuilder) Steps() []GraphTransformer { // Destruction ordering. We require this only so that // targeting below will prune the correct things. &DestroyEdgeTransformer{ - Config: b.Config, - State: b.State, - Schemas: b.Schemas, + Config: b.Config, + State: b.State, }, &TargetsTransformer{Targets: b.Targets}, diff --git a/internal/terraform/graph_builder_eval.go b/internal/terraform/graph_builder_eval.go index f413dd7fe..ee9d6b8e8 100644 --- a/internal/terraform/graph_builder_eval.go +++ b/internal/terraform/graph_builder_eval.go @@ -33,10 +33,6 @@ type EvalGraphBuilder struct { // Plugins is a library of plug-in components (providers and // provisioners) available for use. Plugins *contextPlugins - - // Schemas is the repository of schemas we will draw from to analyse - // the configuration. - Schemas *Schemas } // See GraphBuilder @@ -79,7 +75,7 @@ func (b *EvalGraphBuilder) Steps() []GraphTransformer { // Must attach schemas before ReferenceTransformer so that we can // analyze the configuration to find references. - &AttachSchemaTransformer{Schemas: b.Schemas, Config: b.Config}, + &AttachSchemaTransformer{Plugins: b.Plugins, Config: b.Config}, // Create expansion nodes for all of the module calls. This must // come after all other transformers that create nodes representing diff --git a/internal/terraform/graph_builder_import.go b/internal/terraform/graph_builder_import.go index d502b131e..9910354cf 100644 --- a/internal/terraform/graph_builder_import.go +++ b/internal/terraform/graph_builder_import.go @@ -20,10 +20,6 @@ type ImportGraphBuilder struct { // Plugins is a library of plug-in components (providers and // provisioners) available for use. Plugins *contextPlugins - - // Schemas is the repository of schemas we will draw from to analyse - // the configuration. - Schemas *Schemas } // Build builds the graph according to the steps returned by Steps. @@ -72,7 +68,7 @@ func (b *ImportGraphBuilder) Steps() []GraphTransformer { // Must attach schemas before ReferenceTransformer so that we can // analyze the configuration to find references. - &AttachSchemaTransformer{Schemas: b.Schemas, Config: b.Config}, + &AttachSchemaTransformer{Plugins: b.Plugins, Config: b.Config}, // Create expansion nodes for all of the module calls. This must // come after all other transformers that create nodes representing diff --git a/internal/terraform/graph_builder_plan.go b/internal/terraform/graph_builder_plan.go index e0a355d47..b267f9c42 100644 --- a/internal/terraform/graph_builder_plan.go +++ b/internal/terraform/graph_builder_plan.go @@ -32,10 +32,6 @@ type PlanGraphBuilder struct { // provisioners) available for use. Plugins *contextPlugins - // Schemas is the repository of schemas we will draw from to analyse - // the configuration. - Schemas *Schemas - // Targets are resources to target Targets []addrs.Targetable @@ -137,7 +133,7 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer { // Must attach schemas before ReferenceTransformer so that we can // analyze the configuration to find references. - &AttachSchemaTransformer{Schemas: b.Schemas, Config: b.Config}, + &AttachSchemaTransformer{Plugins: b.Plugins, Config: b.Config}, // Create expansion nodes for all of the module calls. This must // come after all other transformers that create nodes representing diff --git a/internal/terraform/graph_builder_plan_test.go b/internal/terraform/graph_builder_plan_test.go index c5aa9a455..689f9faff 100644 --- a/internal/terraform/graph_builder_plan_test.go +++ b/internal/terraform/graph_builder_plan_test.go @@ -34,12 +34,6 @@ func TestPlanGraphBuilder(t *testing.T) { b := &PlanGraphBuilder{ Config: testModule(t, "graph-builder-plan-basic"), Plugins: plugins, - Schemas: &Schemas{ - Providers: map[addrs.Provider]*ProviderSchema{ - addrs.NewDefaultProvider("aws"): awsProvider.ProviderSchema(), - addrs.NewDefaultProvider("openstack"): openstackProvider.ProviderSchema(), - }, - }, } g, err := b.Build(addrs.RootModuleInstance) @@ -82,11 +76,6 @@ func TestPlanGraphBuilder_dynamicBlock(t *testing.T) { b := &PlanGraphBuilder{ Config: testModule(t, "graph-builder-plan-dynblock"), Plugins: plugins, - Schemas: &Schemas{ - Providers: map[addrs.Provider]*ProviderSchema{ - addrs.NewDefaultProvider("test"): provider.ProviderSchema(), - }, - }, } g, err := b.Build(addrs.RootModuleInstance) @@ -145,11 +134,6 @@ func TestPlanGraphBuilder_attrAsBlocks(t *testing.T) { b := &PlanGraphBuilder{ Config: testModule(t, "graph-builder-plan-attr-as-blocks"), Plugins: plugins, - Schemas: &Schemas{ - Providers: map[addrs.Provider]*ProviderSchema{ - addrs.NewDefaultProvider("test"): provider.ProviderSchema(), - }, - }, } g, err := b.Build(addrs.RootModuleInstance) @@ -190,7 +174,6 @@ func TestPlanGraphBuilder_targetModule(t *testing.T) { b := &PlanGraphBuilder{ Config: testModule(t, "graph-builder-plan-target-module-provider"), Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), Targets: []addrs.Targetable{ addrs.RootModuleInstance.Child("child2", addrs.NoKey), }, @@ -217,11 +200,6 @@ func TestPlanGraphBuilder_forEach(t *testing.T) { b := &PlanGraphBuilder{ Config: testModule(t, "plan-for-each"), Plugins: plugins, - Schemas: &Schemas{ - Providers: map[addrs.Provider]*ProviderSchema{ - addrs.NewDefaultProvider("aws"): awsProvider.ProviderSchema(), - }, - }, } g, err := b.Build(addrs.RootModuleInstance) diff --git a/internal/terraform/schemas_test.go b/internal/terraform/schemas_test.go index 00b6438ee..044b795a5 100644 --- a/internal/terraform/schemas_test.go +++ b/internal/terraform/schemas_test.go @@ -3,6 +3,7 @@ package terraform import ( "github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/configs/configschema" + "github.com/hashicorp/terraform/internal/providers" ) func simpleTestSchemas() *Schemas { @@ -18,3 +19,47 @@ func simpleTestSchemas() *Schemas { }, } } + +// schemaOnlyProvidersForTesting is a testing helper that constructs a +// plugin library that contains a set of providers that only know how to +// return schema, and will exhibit undefined behavior if used for any other +// purpose. +// +// The intended use for this is in testing components that use schemas to +// drive other behavior, such as reference analysis during graph construction, +// but that don't actually need to interact with providers otherwise. +func schemaOnlyProvidersForTesting(schemas map[addrs.Provider]*ProviderSchema) *contextPlugins { + factories := make(map[addrs.Provider]providers.Factory, len(schemas)) + + for providerAddr, schema := range schemas { + + resp := &providers.GetProviderSchemaResponse{ + Provider: providers.Schema{ + Block: schema.Provider, + }, + ResourceTypes: make(map[string]providers.Schema), + DataSources: make(map[string]providers.Schema), + } + for t, tSchema := range schema.ResourceTypes { + resp.ResourceTypes[t] = providers.Schema{ + Block: tSchema, + Version: int64(schema.ResourceTypeSchemaVersions[t]), + } + } + for t, tSchema := range schema.DataSources { + resp.DataSources[t] = providers.Schema{ + Block: tSchema, + } + } + + provider := &MockProvider{ + GetProviderSchemaResponse: resp, + } + + factories[providerAddr] = func() (providers.Interface, error) { + return provider, nil + } + } + + return newContextPlugins(factories, nil) +} diff --git a/internal/terraform/transform_attach_schema.go b/internal/terraform/transform_attach_schema.go index b013931f1..8f7a59083 100644 --- a/internal/terraform/transform_attach_schema.go +++ b/internal/terraform/transform_attach_schema.go @@ -43,15 +43,15 @@ type GraphNodeAttachProvisionerSchema interface { // GraphNodeAttachProvisionerSchema, looks up the needed schemas for each // and then passes them to a method implemented by the node. type AttachSchemaTransformer struct { - Schemas *Schemas + Plugins *contextPlugins Config *configs.Config } func (t *AttachSchemaTransformer) Transform(g *Graph) error { - if t.Schemas == nil { + if t.Plugins == nil { // Should never happen with a reasonable caller, but we'll return a // proper error here anyway so that we'll fail gracefully. - return fmt.Errorf("AttachSchemaTransformer used with nil Schemas") + return fmt.Errorf("AttachSchemaTransformer used with nil Plugins") } for _, v := range g.Vertices() { @@ -62,7 +62,10 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error { typeName := addr.Resource.Type providerFqn := tv.Provider() - schema, version := t.Schemas.ResourceTypeConfig(providerFqn, mode, typeName) + schema, version, err := t.Plugins.ResourceTypeSchema(providerFqn, mode, typeName) + if err != nil { + return fmt.Errorf("failed to read schema for %s in %s: %s", addr, providerFqn, err) + } if schema == nil { log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr) continue @@ -73,8 +76,10 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error { if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok { providerAddr := tv.ProviderAddr() - schema := t.Schemas.ProviderConfig(providerAddr.Provider) - + schema, err := t.Plugins.ProviderConfigSchema(providerAddr.Provider) + if err != nil { + return fmt.Errorf("failed to read provider configuration schema for %s: %s", providerAddr.Provider, err) + } if schema == nil { log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr) continue @@ -86,7 +91,10 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error { if tv, ok := v.(GraphNodeAttachProvisionerSchema); ok { names := tv.ProvisionedBy() for _, name := range names { - schema := t.Schemas.ProvisionerConfig(name) + schema, err := t.Plugins.ProvisionerSchema(name) + if err != nil { + return fmt.Errorf("failed to read provisioner configuration schema for %q: %s", name, err) + } if schema == nil { log.Printf("[ERROR] AttachSchemaTransformer: No schema available for provisioner %q on %q", name, dag.VertexName(v)) continue diff --git a/internal/terraform/transform_destroy_cbd.go b/internal/terraform/transform_destroy_cbd.go index 5650d1a92..cc6c2c15d 100644 --- a/internal/terraform/transform_destroy_cbd.go +++ b/internal/terraform/transform_destroy_cbd.go @@ -115,11 +115,6 @@ type CBDEdgeTransformer struct { // any way possible. Either can be nil if not availabile. Config *configs.Config State *states.State - - // If configuration is present then Schemas is required in order to - // obtain schema information from providers and provisioners so we can - // properly resolve implicit dependencies. - Schemas *Schemas } func (t *CBDEdgeTransformer) Transform(g *Graph) error { diff --git a/internal/terraform/transform_destroy_cbd_test.go b/internal/terraform/transform_destroy_cbd_test.go index a66243f54..629ca5477 100644 --- a/internal/terraform/transform_destroy_cbd_test.go +++ b/internal/terraform/transform_destroy_cbd_test.go @@ -17,7 +17,6 @@ func cbdTestGraph(t *testing.T, mod string, changes *plans.Changes, state *state Config: module, Changes: changes, Plugins: simpleMockPluginLibrary(), - Schemas: simpleTestSchemas(), State: state, } g, err := (&BasicGraphBuilder{ diff --git a/internal/terraform/transform_destroy_edge.go b/internal/terraform/transform_destroy_edge.go index 83ebb0758..521acced0 100644 --- a/internal/terraform/transform_destroy_edge.go +++ b/internal/terraform/transform_destroy_edge.go @@ -45,11 +45,6 @@ type DestroyEdgeTransformer struct { // to determine what a destroy node depends on. Any of these can be nil. Config *configs.Config State *states.State - - // If configuration is present then Schemas is required in order to - // obtain schema information from providers and provisioners in order - // to properly resolve implicit dependencies. - Schemas *Schemas } func (t *DestroyEdgeTransformer) Transform(g *Graph) error { diff --git a/internal/terraform/transform_destroy_edge_test.go b/internal/terraform/transform_destroy_edge_test.go index 902baec4f..a5176a3cc 100644 --- a/internal/terraform/transform_destroy_edge_test.go +++ b/internal/terraform/transform_destroy_edge_test.go @@ -38,8 +38,7 @@ func TestDestroyEdgeTransformer_basic(t *testing.T) { } tf := &DestroyEdgeTransformer{ - Config: testModule(t, "transform-destroy-edge-basic"), - Schemas: simpleTestSchemas(), + Config: testModule(t, "transform-destroy-edge-basic"), } if err := tf.Transform(&g); err != nil { t.Fatalf("err: %s", err) @@ -95,8 +94,7 @@ func TestDestroyEdgeTransformer_multi(t *testing.T) { } tf := &DestroyEdgeTransformer{ - Config: testModule(t, "transform-destroy-edge-multi"), - Schemas: simpleTestSchemas(), + Config: testModule(t, "transform-destroy-edge-multi"), } if err := tf.Transform(&g); err != nil { t.Fatalf("err: %s", err) @@ -113,8 +111,7 @@ func TestDestroyEdgeTransformer_selfRef(t *testing.T) { g := Graph{Path: addrs.RootModuleInstance} g.Add(testDestroyNode("test_object.A")) tf := &DestroyEdgeTransformer{ - Config: testModule(t, "transform-destroy-edge-self-ref"), - Schemas: simpleTestSchemas(), + Config: testModule(t, "transform-destroy-edge-self-ref"), } if err := tf.Transform(&g); err != nil { t.Fatalf("err: %s", err) @@ -157,8 +154,7 @@ func TestDestroyEdgeTransformer_module(t *testing.T) { } tf := &DestroyEdgeTransformer{ - Config: testModule(t, "transform-destroy-edge-module"), - Schemas: simpleTestSchemas(), + Config: testModule(t, "transform-destroy-edge-module"), } if err := tf.Transform(&g); err != nil { t.Fatalf("err: %s", err) @@ -219,8 +215,7 @@ func TestDestroyEdgeTransformer_moduleOnly(t *testing.T) { } tf := &DestroyEdgeTransformer{ - Config: testModule(t, "transform-destroy-edge-module-only"), - Schemas: simpleTestSchemas(), + Config: testModule(t, "transform-destroy-edge-module-only"), } if err := tf.Transform(&g); err != nil { t.Fatalf("err: %s", err) @@ -297,8 +292,7 @@ resource "test_instance" "a" { `, }) tf := &DestroyEdgeTransformer{ - Config: m, - Schemas: simpleTestSchemas(), + Config: m, } if err := tf.Transform(&g); err != nil { t.Fatalf("err: %s", err) diff --git a/internal/terraform/transform_transitive_reduction_test.go b/internal/terraform/transform_transitive_reduction_test.go index e1e744b15..1339d071f 100644 --- a/internal/terraform/transform_transitive_reduction_test.go +++ b/internal/terraform/transform_transitive_reduction_test.go @@ -30,26 +30,24 @@ func TestTransitiveReductionTransformer(t *testing.T) { { transform := &AttachSchemaTransformer{ - Schemas: &Schemas{ - Providers: map[addrs.Provider]*ProviderSchema{ - addrs.NewDefaultProvider("aws"): { - ResourceTypes: map[string]*configschema.Block{ - "aws_instance": &configschema.Block{ - Attributes: map[string]*configschema.Attribute{ - "A": { - Type: cty.String, - Optional: true, - }, - "B": { - Type: cty.String, - Optional: true, - }, + Plugins: schemaOnlyProvidersForTesting(map[addrs.Provider]*ProviderSchema{ + addrs.NewDefaultProvider("aws"): { + ResourceTypes: map[string]*configschema.Block{ + "aws_instance": { + Attributes: map[string]*configschema.Attribute{ + "A": { + Type: cty.String, + Optional: true, + }, + "B": { + Type: cty.String, + Optional: true, }, }, }, }, }, - }, + }), } if err := transform.Transform(&g); err != nil { t.Fatalf("err: %s", err)