providers: A type for all schemas for a particular provider
Previously the "providers" package contained only a type for representing the schema of a particular object within a provider, and the terraform package had the responsibility of aggregating many of those together to describe the entire surface area of a provider. Here we move what was previously terraform.ProviderSchema to instead be providers.Schemas, retaining its existing API otherwise, and leave behind a type alias to allow us to gradually update other references over time. We've gradually been shrinking down the responsibilities of the "terraform" package to just representing the graph components and behaviors anyway, but the specific motivation for doing this _now_ is to allow for other packages to both be called by the terraform package _and_ work with provider schemas at the same time, without creating a package dependency cycle: instead, these other packages can just import the "providers" package and not need to import the "terraform" package at all. For now this does still leave the responsibility for _building_ a providers.Schemas object over in the "terraform" package, because it's currently doing that as part of some larger work that isn't easily separable, and so reorganizing that would be a more involved and riskier change than just moving the existing type elsewhere.
This commit is contained in:
parent
2453025a1a
commit
1425374371
|
@ -3,7 +3,6 @@ package providers
|
||||||
import (
|
import (
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/configs/configschema"
|
|
||||||
"github.com/hashicorp/terraform/internal/states"
|
"github.com/hashicorp/terraform/internal/states"
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
)
|
)
|
||||||
|
@ -88,13 +87,6 @@ type GetProviderSchemaResponse struct {
|
||||||
Diagnostics tfdiags.Diagnostics
|
Diagnostics tfdiags.Diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schema pairs a provider or resource schema with that schema's version.
|
|
||||||
// This is used to be able to upgrade the schema in UpgradeResourceState.
|
|
||||||
type Schema struct {
|
|
||||||
Version int64
|
|
||||||
Block *configschema.Block
|
|
||||||
}
|
|
||||||
|
|
||||||
type ValidateProviderConfigRequest struct {
|
type ValidateProviderConfigRequest struct {
|
||||||
// Config is the raw configuration value for the provider.
|
// Config is the raw configuration value for the provider.
|
||||||
Config cty.Value
|
Config cty.Value
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package providers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/internal/addrs"
|
||||||
|
"github.com/hashicorp/terraform/internal/configs/configschema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Schemas is an overall container for all of the schemas for all configurable
|
||||||
|
// objects defined within a particular provider.
|
||||||
|
//
|
||||||
|
// The schema for each individual configurable object is represented by nested
|
||||||
|
// instances of type Schema (singular) within this data structure.
|
||||||
|
//
|
||||||
|
// This type used to be known as terraform.ProviderSchema, but moved out here
|
||||||
|
// as part of our ongoing efforts to shrink down the "terraform" package.
|
||||||
|
// There's still a type alias at the old name, but we should prefer using
|
||||||
|
// providers.Schema in new code. However, a consequence of this transitional
|
||||||
|
// situation is that the "terraform" package still has the responsibility for
|
||||||
|
// constructing a providers.Schemas object based on responses from the provider
|
||||||
|
// API; hopefully we'll continue this refactor later so that functions in this
|
||||||
|
// package totally encapsulate the unmarshalling and include this as part of
|
||||||
|
// providers.GetProviderSchemaResponse.
|
||||||
|
type Schemas struct {
|
||||||
|
Provider *configschema.Block
|
||||||
|
ProviderMeta *configschema.Block
|
||||||
|
ResourceTypes 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 (ss *Schemas) SchemaForResourceType(mode addrs.ResourceMode, typeName string) (schema *configschema.Block, version uint64) {
|
||||||
|
switch mode {
|
||||||
|
case addrs.ManagedResourceMode:
|
||||||
|
return ss.ResourceTypes[typeName], ss.ResourceTypeSchemaVersions[typeName]
|
||||||
|
case addrs.DataResourceMode:
|
||||||
|
// Data resources don't have schema versions right now, since state is discarded for each refresh
|
||||||
|
return ss.DataSources[typeName], 0
|
||||||
|
default:
|
||||||
|
// Shouldn't happen, because the above cases are comprehensive.
|
||||||
|
return nil, 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SchemaForResourceAddr attempts to find a schema for the mode and type from
|
||||||
|
// the given resource address. Returns nil if no such schema is available.
|
||||||
|
func (ss *Schemas) SchemaForResourceAddr(addr addrs.Resource) (schema *configschema.Block, version uint64) {
|
||||||
|
return ss.SchemaForResourceType(addr.Mode, addr.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema pairs a provider or resource schema with that schema's version.
|
||||||
|
// This is used to be able to upgrade the schema in UpgradeResourceState.
|
||||||
|
//
|
||||||
|
// This describes the schema for a single object within a provider. Type
|
||||||
|
// "Schemas" (plural) instead represents the overall collection of schemas
|
||||||
|
// for everything within a particular provider.
|
||||||
|
type Schema struct {
|
||||||
|
Version int64
|
||||||
|
Block *configschema.Block
|
||||||
|
}
|
|
@ -12,10 +12,16 @@ import (
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ProviderSchema is an alias for providers.Schemas, which is the new location
|
||||||
|
// for what we originally called terraform.ProviderSchema but which has
|
||||||
|
// moved out as part of ongoing refactoring to shrink down the main "terraform"
|
||||||
|
// package.
|
||||||
|
type ProviderSchema = providers.Schemas
|
||||||
|
|
||||||
// Schemas is a container for various kinds of schema that Terraform needs
|
// Schemas is a container for various kinds of schema that Terraform needs
|
||||||
// during processing.
|
// during processing.
|
||||||
type Schemas struct {
|
type Schemas struct {
|
||||||
Providers map[addrs.Provider]*ProviderSchema
|
Providers map[addrs.Provider]*providers.Schemas
|
||||||
Provisioners map[string]*configschema.Block
|
Provisioners map[string]*configschema.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +30,7 @@ type Schemas struct {
|
||||||
//
|
//
|
||||||
// It's usually better to go use the more precise methods offered by type
|
// It's usually better to go use the more precise methods offered by type
|
||||||
// Schemas to handle this detail automatically.
|
// Schemas to handle this detail automatically.
|
||||||
func (ss *Schemas) ProviderSchema(provider addrs.Provider) *ProviderSchema {
|
func (ss *Schemas) ProviderSchema(provider addrs.Provider) *providers.Schemas {
|
||||||
if ss.Providers == nil {
|
if ss.Providers == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -76,7 +82,7 @@ func (ss *Schemas) ProvisionerConfig(name string) *configschema.Block {
|
||||||
// still valid but may be incomplete.
|
// still valid but may be incomplete.
|
||||||
func loadSchemas(config *configs.Config, state *states.State, plugins *contextPlugins) (*Schemas, error) {
|
func loadSchemas(config *configs.Config, state *states.State, plugins *contextPlugins) (*Schemas, error) {
|
||||||
schemas := &Schemas{
|
schemas := &Schemas{
|
||||||
Providers: map[addrs.Provider]*ProviderSchema{},
|
Providers: map[addrs.Provider]*providers.Schemas{},
|
||||||
Provisioners: map[string]*configschema.Block{},
|
Provisioners: map[string]*configschema.Block{},
|
||||||
}
|
}
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
|
@ -89,7 +95,7 @@ func loadSchemas(config *configs.Config, state *states.State, plugins *contextPl
|
||||||
return schemas, diags.Err()
|
return schemas, diags.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadProviderSchemas(schemas map[addrs.Provider]*ProviderSchema, config *configs.Config, state *states.State, plugins *contextPlugins) tfdiags.Diagnostics {
|
func loadProviderSchemas(schemas map[addrs.Provider]*providers.Schemas, config *configs.Config, state *states.State, plugins *contextPlugins) tfdiags.Diagnostics {
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
|
|
||||||
ensure := func(fqn addrs.Provider) {
|
ensure := func(fqn addrs.Provider) {
|
||||||
|
@ -105,7 +111,7 @@ func loadProviderSchemas(schemas map[addrs.Provider]*ProviderSchema, config *con
|
||||||
// We'll put a stub in the map so we won't re-attempt this on
|
// We'll put a stub in the map so we won't re-attempt this on
|
||||||
// future calls, which would then repeat the same error message
|
// future calls, which would then repeat the same error message
|
||||||
// multiple times.
|
// multiple times.
|
||||||
schemas[fqn] = &ProviderSchema{}
|
schemas[fqn] = &providers.Schemas{}
|
||||||
diags = diags.Append(
|
diags = diags.Append(
|
||||||
tfdiags.Sourceless(
|
tfdiags.Sourceless(
|
||||||
tfdiags.Error,
|
tfdiags.Error,
|
||||||
|
@ -179,39 +185,3 @@ func loadProvisionerSchemas(schemas map[string]*configschema.Block, config *conf
|
||||||
|
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProviderSchema represents the schema for a provider's own configuration
|
|
||||||
// and the configuration for some or all of its resources and data sources.
|
|
||||||
//
|
|
||||||
// The completeness of this structure depends on how it was constructed.
|
|
||||||
// When constructed for a configuration, it will generally include only
|
|
||||||
// resource types and data sources used by that configuration.
|
|
||||||
type ProviderSchema struct {
|
|
||||||
Provider *configschema.Block
|
|
||||||
ProviderMeta *configschema.Block
|
|
||||||
ResourceTypes 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) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SchemaForResourceAddr attempts to find a schema for the mode and type from
|
|
||||||
// the given resource address. Returns nil if no such schema is available.
|
|
||||||
func (ps *ProviderSchema) SchemaForResourceAddr(addr addrs.Resource) (schema *configschema.Block, version uint64) {
|
|
||||||
return ps.SchemaForResourceType(addr.Mode, addr.Type)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue