mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
168d84b3c4
Previously we were fetching these from the provider but then immediately discarding the version numbers because the schema API had nowhere to put them. To avoid a late-breaking change to the internal structure of terraform.ProviderSchema (which is constructed directly all over the tests) we're retaining the resource type schemas in a new map alongside the existing one with the same keys, rather than just switching to using the providers.Schema struct directly there. The methods that return resource type schemas now return two arguments, intentionally creating a little API friction here so each new caller can be reminded to think about whether they need to do something with the schema version, though it can be ignored by many callers. Since this was a breaking change to the Schemas API anyway, this also fixes another API wart where there was a separate method for fetching managed vs. data resource types and thus every caller ended up having a switch statement on "mode". Now we just accept mode as an argument and do the switch statement within the single SchemaForResourceType method.
100 lines
3.4 KiB
Go
100 lines
3.4 KiB
Go
package terraform
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/hashicorp/terraform/configs/configschema"
|
|
"github.com/hashicorp/terraform/dag"
|
|
)
|
|
|
|
// GraphNodeAttachResourceSchema is an interface implemented by node types
|
|
// that need a resource schema attached.
|
|
type GraphNodeAttachResourceSchema interface {
|
|
GraphNodeResource
|
|
GraphNodeProviderConsumer
|
|
|
|
AttachResourceSchema(schema *configschema.Block, version uint64)
|
|
}
|
|
|
|
// GraphNodeAttachProviderConfigSchema is an interface implemented by node types
|
|
// that need a provider configuration schema attached.
|
|
type GraphNodeAttachProviderConfigSchema interface {
|
|
GraphNodeProvider
|
|
|
|
AttachProviderConfigSchema(*configschema.Block)
|
|
}
|
|
|
|
// GraphNodeAttachProvisionerSchema is an interface implemented by node types
|
|
// that need one or more provisioner schemas attached.
|
|
type GraphNodeAttachProvisionerSchema interface {
|
|
ProvisionedBy() []string
|
|
|
|
// SetProvisionerSchema is called during transform for each provisioner
|
|
// type returned from ProvisionedBy, providing the configuration schema
|
|
// for each provisioner in turn. The implementer should save these for
|
|
// later use in evaluating provisioner configuration blocks.
|
|
AttachProvisionerSchema(name string, schema *configschema.Block)
|
|
}
|
|
|
|
// AttachSchemaTransformer finds nodes that implement
|
|
// GraphNodeAttachResourceSchema, GraphNodeAttachProviderConfigSchema, or
|
|
// GraphNodeAttachProvisionerSchema, looks up the needed schemas for each
|
|
// and then passes them to a method implemented by the node.
|
|
type AttachSchemaTransformer struct {
|
|
Schemas *Schemas
|
|
}
|
|
|
|
func (t *AttachSchemaTransformer) Transform(g *Graph) error {
|
|
if t.Schemas == 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")
|
|
}
|
|
|
|
for _, v := range g.Vertices() {
|
|
|
|
if tv, ok := v.(GraphNodeAttachResourceSchema); ok {
|
|
addr := tv.ResourceAddr()
|
|
mode := addr.Resource.Mode
|
|
typeName := addr.Resource.Type
|
|
providerAddr, _ := tv.ProvidedBy()
|
|
providerType := providerAddr.ProviderConfig.Type
|
|
|
|
schema, version := t.Schemas.ResourceTypeConfig(providerType, mode, typeName)
|
|
if schema == nil {
|
|
log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr)
|
|
continue
|
|
}
|
|
log.Printf("[TRACE] AttachSchemaTransformer: attaching resource schema to %s", dag.VertexName(v))
|
|
tv.AttachResourceSchema(schema, version)
|
|
}
|
|
|
|
if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok {
|
|
providerAddr := tv.ProviderAddr()
|
|
schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.Type)
|
|
if schema == nil {
|
|
log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr)
|
|
continue
|
|
}
|
|
log.Printf("[TRACE] AttachSchemaTransformer: attaching provider config schema to %s", dag.VertexName(v))
|
|
tv.AttachProviderConfigSchema(schema)
|
|
}
|
|
|
|
if tv, ok := v.(GraphNodeAttachProvisionerSchema); ok {
|
|
names := tv.ProvisionedBy()
|
|
for _, name := range names {
|
|
schema := t.Schemas.ProvisionerConfig(name)
|
|
if schema == nil {
|
|
log.Printf("[ERROR] AttachSchemaTransformer: No schema available for provisioner %q on %q", name, dag.VertexName(v))
|
|
continue
|
|
}
|
|
log.Printf("[TRACE] AttachSchemaTransformer: attaching provisioner %q config schema to %s", name, dag.VertexName(v))
|
|
tv.AttachProvisionerSchema(name, schema)
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|