core: Make resource type schema versions visible to callers
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.
This commit is contained in:
parent
6daf4989d4
commit
168d84b3c4
|
@ -245,7 +245,7 @@ func (b *Local) renderPlan(plan *plans.Plan, schemas *terraform.Schemas) {
|
||||||
b.CLI.Output(fmt.Sprintf("(schema missing for %s)\n", rcs.ProviderAddr))
|
b.CLI.Output(fmt.Sprintf("(schema missing for %s)\n", rcs.ProviderAddr))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
rSchema := providerSchema.SchemaForResourceAddr(rcs.Addr.Resource.Resource)
|
rSchema, _ := providerSchema.SchemaForResourceAddr(rcs.Addr.Resource.Resource)
|
||||||
if rSchema == nil {
|
if rSchema == nil {
|
||||||
// Should never happen
|
// Should never happen
|
||||||
b.CLI.Output(fmt.Sprintf("(schema missing for %s)\n", rcs.Addr))
|
b.CLI.Output(fmt.Sprintf("(schema missing for %s)\n", rcs.Addr))
|
||||||
|
|
|
@ -46,7 +46,7 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
state = &states.ResourceInstanceObject{}
|
state = &states.ResourceInstanceObject{}
|
||||||
}
|
}
|
||||||
|
|
||||||
schema := (*n.ProviderSchema).ResourceTypes[n.Addr.Resource.Type]
|
schema, _ := (*n.ProviderSchema).SchemaForResourceType(n.Addr.Resource.Mode, n.Addr.Resource.Type)
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
||||||
|
|
|
@ -43,10 +43,10 @@ func (n *EvalCheckPlannedChange) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
plannedChange := *n.Planned
|
plannedChange := *n.Planned
|
||||||
actualChange := *n.Actual
|
actualChange := *n.Actual
|
||||||
|
|
||||||
schema := providerSchema.ResourceTypes[n.Addr.Resource.Type]
|
schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support %q", n.Addr.Resource.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
|
@ -129,7 +129,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
|
|
||||||
// Evaluate the configuration
|
// Evaluate the configuration
|
||||||
schema := providerSchema.ResourceTypes[n.Addr.Resource.Type]
|
schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
||||||
|
@ -833,7 +833,7 @@ func (n *EvalReadDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
changes := ctx.Changes()
|
changes := ctx.Changes()
|
||||||
addr := n.Addr.Absolute(ctx.Path())
|
addr := n.Addr.Absolute(ctx.Path())
|
||||||
|
|
||||||
schema := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
||||||
|
@ -894,7 +894,7 @@ func (n *EvalWriteDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
panic("inconsistent address and/or deposed key in EvalWriteDiff")
|
panic("inconsistent address and/or deposed key in EvalWriteDiff")
|
||||||
}
|
}
|
||||||
|
|
||||||
schema := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
||||||
|
|
|
@ -83,7 +83,7 @@ func (n *EvalReadData) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
config := *n.Config
|
config := *n.Config
|
||||||
provider := *n.Provider
|
provider := *n.Provider
|
||||||
providerSchema := *n.ProviderSchema
|
providerSchema := *n.ProviderSchema
|
||||||
schema := providerSchema.DataSources[n.Addr.Resource.Type]
|
schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider %q does not support data source %q", n.ProviderAddr.ProviderConfig.Type, n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider %q does not support data source %q", n.ProviderAddr.ProviderConfig.Type, n.Addr.Resource.Type)
|
||||||
|
@ -322,7 +322,7 @@ func (n *EvalReadDataDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
} else {
|
} else {
|
||||||
config := *n.Config
|
config := *n.Config
|
||||||
providerSchema := *n.ProviderSchema
|
providerSchema := *n.ProviderSchema
|
||||||
schema := providerSchema.DataSources[n.Addr.Resource.Type]
|
schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider does not support data source %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support data source %q", n.Addr.Resource.Type)
|
||||||
|
@ -440,7 +440,7 @@ func (n *EvalReadDataApply) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, diags.Err()
|
return nil, diags.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
schema := providerSchema.DataSources[n.Addr.Resource.Type]
|
schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider does not support data source %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support data source %q", n.Addr.Resource.Type)
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, diags.ErrWithWarnings()
|
return nil, diags.ErrWithWarnings()
|
||||||
}
|
}
|
||||||
|
|
||||||
schema := (*n.ProviderSchema).ResourceTypes[n.Addr.Resource.Type]
|
schema, _ := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Should be caught during validation, so we don't bother with a pretty error here
|
// Should be caught during validation, so we don't bother with a pretty error here
|
||||||
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
||||||
|
|
|
@ -49,16 +49,11 @@ func (n *EvalReadState) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Update n.ResourceTypeSchema to be a providers.Schema and then
|
schema, currentVersion := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
// check the version number here and upgrade if necessary.
|
if src.SchemaVersion < currentVersion {
|
||||||
/*
|
// TODO: Implement schema upgrades
|
||||||
if src.SchemaVersion < n.ResourceTypeSchema.Version {
|
return nil, fmt.Errorf("schema upgrading is not yet implemented to take state from version %d to version %d", src.SchemaVersion, currentVersion)
|
||||||
// TODO: Implement schema upgrades
|
}
|
||||||
return nil, fmt.Errorf("schema upgrading is not yet implemented to take state from version %d to version %d", src.SchemaVersion, n.ResourceTypeSchema.Version)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
schema := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
|
||||||
|
|
||||||
obj, err := src.Decode(schema.ImpliedType())
|
obj, err := src.Decode(schema.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -107,16 +102,12 @@ func (n *EvalReadStateDeposed) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Update n.ResourceTypeSchema to be a providers.Schema and then
|
schema, currentVersion := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
// check the version number here and upgrade if necessary.
|
if src.SchemaVersion < currentVersion {
|
||||||
/*
|
// TODO: Implement schema upgrades
|
||||||
if src.SchemaVersion < n.ResourceTypeSchema.Version {
|
return nil, fmt.Errorf("schema upgrading is not yet implemented to take state from version %d to version %d", src.SchemaVersion, currentVersion)
|
||||||
// TODO: Implement schema upgrades
|
}
|
||||||
return nil, fmt.Errorf("schema upgrading is not yet implemented to take state from version %d to version %d", src.SchemaVersion, n.ResourceTypeSchema.Version)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
schema := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
|
||||||
obj, err := src.Decode(schema.ImpliedType())
|
obj, err := src.Decode(schema.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -216,16 +207,14 @@ func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
log.Printf("[TRACE] EvalWriteState: removing current state object for %s", absAddr)
|
log.Printf("[TRACE] EvalWriteState: removing current state object for %s", absAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Update this to use providers.Schema and populate the real
|
schema, currentVersion := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
// schema version in the second argument to Encode below.
|
|
||||||
schema := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// It shouldn't be possible to get this far in any real scenario
|
// It shouldn't be possible to get this far in any real scenario
|
||||||
// without a schema, but we might end up here in contrived tests that
|
// without a schema, but we might end up here in contrived tests that
|
||||||
// fail to set up their world properly.
|
// fail to set up their world properly.
|
||||||
return nil, fmt.Errorf("failed to encode %s in state: no resource type schema available", absAddr)
|
return nil, fmt.Errorf("failed to encode %s in state: no resource type schema available", absAddr)
|
||||||
}
|
}
|
||||||
src, err := obj.Encode(schema.ImpliedType(), 0)
|
src, err := obj.Encode(schema.ImpliedType(), currentVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to encode %s in state: %s", absAddr, err)
|
return nil, fmt.Errorf("failed to encode %s in state: %s", absAddr, err)
|
||||||
}
|
}
|
||||||
|
@ -282,16 +271,14 @@ func (n *EvalWriteStateDeposed) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
panic("EvalWriteStateDeposed used with no ProviderSchema object")
|
panic("EvalWriteStateDeposed used with no ProviderSchema object")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Update this to use providers.Schema and populate the real
|
schema, currentVersion := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
||||||
// schema version in the second argument to Encode below.
|
|
||||||
schema := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource())
|
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// It shouldn't be possible to get this far in any real scenario
|
// It shouldn't be possible to get this far in any real scenario
|
||||||
// without a schema, but we might end up here in contrived tests that
|
// without a schema, but we might end up here in contrived tests that
|
||||||
// fail to set up their world properly.
|
// fail to set up their world properly.
|
||||||
return nil, fmt.Errorf("failed to encode %s in state: no resource type schema available", absAddr)
|
return nil, fmt.Errorf("failed to encode %s in state: no resource type schema available", absAddr)
|
||||||
}
|
}
|
||||||
src, err := obj.Encode(schema.ImpliedType(), 0)
|
src, err := obj.Encode(schema.ImpliedType(), currentVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to encode %s in state: %s", absAddr, err)
|
return nil, fmt.Errorf("failed to encode %s in state: %s", absAddr, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,8 +373,8 @@ func (n *EvalValidateResource) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
// in the provider abstraction.
|
// in the provider abstraction.
|
||||||
switch mode {
|
switch mode {
|
||||||
case addrs.ManagedResourceMode:
|
case addrs.ManagedResourceMode:
|
||||||
schema, exists := schema.ResourceTypes[cfg.Type]
|
schema, _ := schema.SchemaForResourceType(mode, cfg.Type)
|
||||||
if !exists {
|
if schema == nil {
|
||||||
diags = diags.Append(&hcl.Diagnostic{
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Invalid resource type",
|
Summary: "Invalid resource type",
|
||||||
|
@ -403,8 +403,8 @@ func (n *EvalValidateResource) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case addrs.DataResourceMode:
|
case addrs.DataResourceMode:
|
||||||
schema, exists := schema.DataSources[cfg.Type]
|
schema, _ := schema.SchemaForResourceType(mode, cfg.Type)
|
||||||
if !exists {
|
if schema == nil {
|
||||||
diags = diags.Append(&hcl.Diagnostic{
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Invalid data source",
|
Summary: "Invalid data source",
|
||||||
|
|
|
@ -40,19 +40,9 @@ func (n *EvalValidateSelfRef) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
var schema *configschema.Block
|
var schema *configschema.Block
|
||||||
switch tAddr := addr.(type) {
|
switch tAddr := addr.(type) {
|
||||||
case addrs.Resource:
|
case addrs.Resource:
|
||||||
switch tAddr.Mode {
|
schema, _ = providerSchema.SchemaForResourceAddr(tAddr)
|
||||||
case addrs.ManagedResourceMode:
|
|
||||||
schema = providerSchema.ResourceTypes[tAddr.Type]
|
|
||||||
case addrs.DataResourceMode:
|
|
||||||
schema = providerSchema.DataSources[tAddr.Type]
|
|
||||||
}
|
|
||||||
case addrs.ResourceInstance:
|
case addrs.ResourceInstance:
|
||||||
switch tAddr.Resource.Mode {
|
schema, _ = providerSchema.SchemaForResourceAddr(tAddr.ContainingResource())
|
||||||
case addrs.ManagedResourceMode:
|
|
||||||
schema = providerSchema.ResourceTypes[tAddr.Resource.Type]
|
|
||||||
case addrs.DataResourceMode:
|
|
||||||
schema = providerSchema.DataSources[tAddr.Resource.Type]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
|
|
|
@ -798,17 +798,9 @@ func (d *evaluationStateData) getResourceInstancesAll(addr addrs.Resource, rng t
|
||||||
|
|
||||||
func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAddr addrs.AbsProviderConfig) *configschema.Block {
|
func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAddr addrs.AbsProviderConfig) *configschema.Block {
|
||||||
providerType := providerAddr.ProviderConfig.Type
|
providerType := providerAddr.ProviderConfig.Type
|
||||||
typeName := addr.Type
|
|
||||||
schemas := d.Evaluator.Schemas
|
schemas := d.Evaluator.Schemas
|
||||||
switch addr.Mode {
|
schema, _ := schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type)
|
||||||
case addrs.ManagedResourceMode:
|
return schema
|
||||||
return schemas.ResourceTypeConfig(providerType, typeName)
|
|
||||||
case addrs.DataResourceMode:
|
|
||||||
return schemas.DataSourceConfig(providerType, typeName)
|
|
||||||
default:
|
|
||||||
log.Printf("[WARN] Don't know how to fetch schema for resource %s", providerAddr)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// coerceInstanceKey attempts to convert the given key to the type expected
|
// coerceInstanceKey attempts to convert the given key to the type expected
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -112,13 +111,7 @@ func (d *evaluationStateData) staticValidateResourceReference(modCfg *configs.Co
|
||||||
// account provider inheritance, etc but it's okay here because we're only
|
// account provider inheritance, etc but it's okay here because we're only
|
||||||
// paying attention to the type anyway.
|
// paying attention to the type anyway.
|
||||||
providerType := cfg.ProviderConfigAddr().Type
|
providerType := cfg.ProviderConfigAddr().Type
|
||||||
var schema *configschema.Block
|
schema, _ := d.Evaluator.Schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type)
|
||||||
switch addr.Mode {
|
|
||||||
case addrs.ManagedResourceMode:
|
|
||||||
schema = d.Evaluator.Schemas.ResourceTypeConfig(providerType, addr.Type)
|
|
||||||
case addrs.DataResourceMode:
|
|
||||||
schema = d.Evaluator.Schemas.DataSourceConfig(providerType, addr.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
// Prior validation should've taken care of a resource block with an
|
// Prior validation should've taken care of a resource block with an
|
||||||
|
|
|
@ -47,8 +47,9 @@ type NodeAbstractResource struct {
|
||||||
// interfaces if you're running those transforms, but also be explicitly
|
// interfaces if you're running those transforms, but also be explicitly
|
||||||
// set if you already have that information.
|
// set if you already have that information.
|
||||||
|
|
||||||
Schema *configschema.Block // Schema for processing the configuration body
|
Schema *configschema.Block // Schema for processing the configuration body
|
||||||
Config *configs.Resource // Config is the resource in the config
|
SchemaVersion uint64 // Schema version of "Schema", as decided by the provider
|
||||||
|
Config *configs.Resource // Config is the resource in the config
|
||||||
|
|
||||||
ProvisionerSchemas map[string]*configschema.Block
|
ProvisionerSchemas map[string]*configschema.Block
|
||||||
|
|
||||||
|
@ -423,8 +424,9 @@ func (n *NodeAbstractResource) AttachResourceConfig(c *configs.Resource) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeAttachResourceSchema impl
|
// GraphNodeAttachResourceSchema impl
|
||||||
func (n *NodeAbstractResource) AttachResourceSchema(schema *configschema.Block) {
|
func (n *NodeAbstractResource) AttachResourceSchema(schema *configschema.Block, version uint64) {
|
||||||
n.Schema = schema
|
n.Schema = schema
|
||||||
|
n.SchemaVersion = version
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeDotter impl.
|
// GraphNodeDotter impl.
|
||||||
|
|
|
@ -50,31 +50,12 @@ func (ss *Schemas) ProviderConfig(typeName string) *configschema.Block {
|
||||||
// a resource using the "provider" meta-argument. Therefore it's important to
|
// a resource using the "provider" meta-argument. Therefore it's important to
|
||||||
// always pass the correct provider name, even though it many cases it feels
|
// always pass the correct provider name, even though it many cases it feels
|
||||||
// redundant.
|
// redundant.
|
||||||
func (ss *Schemas) ResourceTypeConfig(providerType string, resourceType string) *configschema.Block {
|
func (ss *Schemas) ResourceTypeConfig(providerType string, resourceMode addrs.ResourceMode, resourceType string) (block *configschema.Block, schemaVersion uint64) {
|
||||||
ps := ss.ProviderSchema(providerType)
|
ps := ss.ProviderSchema(providerType)
|
||||||
if ps == nil || ps.ResourceTypes == nil {
|
if ps == nil || ps.ResourceTypes == nil {
|
||||||
return nil
|
return nil, 0
|
||||||
}
|
}
|
||||||
|
return ps.SchemaForResourceType(resourceMode, resourceType)
|
||||||
return ps.ResourceTypes[resourceType]
|
|
||||||
}
|
|
||||||
|
|
||||||
// DataSourceConfig returns the schema for the configuration of a given
|
|
||||||
// data source belonging to a given provider type, or nil of no such
|
|
||||||
// schema is available.
|
|
||||||
//
|
|
||||||
// In many cases the provider type is inferrable from the data source name,
|
|
||||||
// but this is not always true because users can override the provider for
|
|
||||||
// a resource using the "provider" meta-argument. Therefore it's important to
|
|
||||||
// always pass the correct provider name, even though it many cases it feels
|
|
||||||
// redundant.
|
|
||||||
func (ss *Schemas) DataSourceConfig(providerType string, dataSource string) *configschema.Block {
|
|
||||||
ps := ss.ProviderSchema(providerType)
|
|
||||||
if ps == nil || ps.DataSources == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return ps.DataSources[dataSource]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvisionerConfig returns the schema for the configuration of a given
|
// ProvisionerConfig returns the schema for the configuration of a given
|
||||||
|
@ -146,10 +127,13 @@ func loadProviderSchemas(schemas map[string]*ProviderSchema, config *configs.Con
|
||||||
Provider: resp.Provider.Block,
|
Provider: resp.Provider.Block,
|
||||||
ResourceTypes: make(map[string]*configschema.Block),
|
ResourceTypes: make(map[string]*configschema.Block),
|
||||||
DataSources: make(map[string]*configschema.Block),
|
DataSources: make(map[string]*configschema.Block),
|
||||||
|
|
||||||
|
ResourceTypeSchemaVersions: make(map[string]uint64),
|
||||||
}
|
}
|
||||||
|
|
||||||
for t, r := range resp.ResourceTypes {
|
for t, r := range resp.ResourceTypes {
|
||||||
s.ResourceTypes[t] = r.Block
|
s.ResourceTypes[t] = r.Block
|
||||||
|
s.ResourceTypeSchemaVersions[t] = r.Version
|
||||||
}
|
}
|
||||||
|
|
||||||
for t, d := range resp.DataSources {
|
for t, d := range resp.DataSources {
|
||||||
|
@ -241,22 +225,32 @@ type ProviderSchema struct {
|
||||||
Provider *configschema.Block
|
Provider *configschema.Block
|
||||||
ResourceTypes map[string]*configschema.Block
|
ResourceTypes map[string]*configschema.Block
|
||||||
DataSources map[string]*configschema.Block
|
DataSources map[string]*configschema.Block
|
||||||
|
|
||||||
|
ResourceTypeSchemaVersions map[string]uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// SchemaForResourceType attempts to find a schema for the given mode and type.
|
||||||
|
// Returns nil if no such schema is available.
|
||||||
|
func (ps *ProviderSchema) SchemaForResourceType(mode addrs.ResourceMode, typeName string) (schema *configschema.Block, version uint64) {
|
||||||
|
var m map[string]providers.Schema
|
||||||
|
switch mode {
|
||||||
|
case addrs.ManagedResourceMode:
|
||||||
|
return ps.ResourceTypes[typeName], ps.ResourceTypeSchemaVersions[typeName]
|
||||||
|
case addrs.DataResourceMode:
|
||||||
|
// Data resources don't have schema versions right now, since state is discarded for each refresh
|
||||||
|
return ps.DataSources[typeName], 0
|
||||||
|
default:
|
||||||
|
// Shouldn't happen, because the above cases are comprehensive.
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
s := m[typeName]
|
||||||
|
return s.Block, s.Version
|
||||||
}
|
}
|
||||||
|
|
||||||
// SchemaForResourceAddr attempts to find a schema for the mode and type from
|
// SchemaForResourceAddr attempts to find a schema for the mode and type from
|
||||||
// the given resource address. Returns nil if no such schema is available.
|
// the given resource address. Returns nil if no such schema is available.
|
||||||
func (ps *ProviderSchema) SchemaForResourceAddr(addr addrs.Resource) *configschema.Block {
|
func (ps *ProviderSchema) SchemaForResourceAddr(addr addrs.Resource) (schema *configschema.Block, version uint64) {
|
||||||
var m map[string]*configschema.Block
|
return ps.SchemaForResourceType(addr.Mode, addr.Type)
|
||||||
switch addr.Mode {
|
|
||||||
case addrs.ManagedResourceMode:
|
|
||||||
m = ps.ResourceTypes
|
|
||||||
case addrs.DataResourceMode:
|
|
||||||
m = ps.DataSources
|
|
||||||
default:
|
|
||||||
// Shouldn't happen, because the above cases are comprehensive.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return m[addr.Type]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProviderSchemaRequest is used to describe to a ResourceProvider which
|
// ProviderSchemaRequest is used to describe to a ResourceProvider which
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
"github.com/hashicorp/terraform/dag"
|
"github.com/hashicorp/terraform/dag"
|
||||||
)
|
)
|
||||||
|
@ -15,7 +14,7 @@ type GraphNodeAttachResourceSchema interface {
|
||||||
GraphNodeResource
|
GraphNodeResource
|
||||||
GraphNodeProviderConsumer
|
GraphNodeProviderConsumer
|
||||||
|
|
||||||
AttachResourceSchema(*configschema.Block)
|
AttachResourceSchema(schema *configschema.Block, version uint64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeAttachProviderConfigSchema is an interface implemented by node types
|
// GraphNodeAttachProviderConfigSchema is an interface implemented by node types
|
||||||
|
@ -62,19 +61,13 @@ func (t *AttachSchemaTransformer) Transform(g *Graph) error {
|
||||||
providerAddr, _ := tv.ProvidedBy()
|
providerAddr, _ := tv.ProvidedBy()
|
||||||
providerType := providerAddr.ProviderConfig.Type
|
providerType := providerAddr.ProviderConfig.Type
|
||||||
|
|
||||||
var schema *configschema.Block
|
schema, version := t.Schemas.ResourceTypeConfig(providerType, mode, typeName)
|
||||||
switch mode {
|
|
||||||
case addrs.ManagedResourceMode:
|
|
||||||
schema = t.Schemas.ResourceTypeConfig(providerType, typeName)
|
|
||||||
case addrs.DataResourceMode:
|
|
||||||
schema = t.Schemas.DataSourceConfig(providerType, typeName)
|
|
||||||
}
|
|
||||||
if schema == nil {
|
if schema == nil {
|
||||||
log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr)
|
log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
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, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok {
|
if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok {
|
||||||
|
|
Loading…
Reference in New Issue