mirror of
https://github.com/opentofu/opentofu.git
synced 2026-05-28 04:15:54 -04:00
Introduce plugin library and managers (#3652)
Some checks are pending
build / Build for freebsd_386 (push) Waiting to run
build / Build for linux_386 (push) Waiting to run
build / Build for openbsd_386 (push) Waiting to run
build / Build for windows_386 (push) Waiting to run
build / Build for freebsd_amd64 (push) Waiting to run
build / Build for linux_amd64 (push) Waiting to run
build / Build for openbsd_amd64 (push) Waiting to run
build / Build for solaris_amd64 (push) Waiting to run
build / Build for windows_amd64 (push) Waiting to run
build / Build for freebsd_arm (push) Waiting to run
build / Build for linux_arm (push) Waiting to run
build / Build for linux_arm64 (push) Waiting to run
build / Build for darwin_amd64 (push) Waiting to run
build / Build for darwin_arm64 (push) Waiting to run
build / End-to-end Tests for linux_386 (push) Waiting to run
build / End-to-end Tests for windows_386 (push) Waiting to run
build / End-to-end Tests for darwin_amd64 (push) Waiting to run
build / End-to-end Tests for linux_amd64 (push) Waiting to run
build / End-to-end Tests for windows_amd64 (push) Waiting to run
Quick Checks / List files changed for pull request (push) Waiting to run
Quick Checks / Unit tests for linux_386 (push) Blocked by required conditions
Quick Checks / Unit tests for linux_amd64 (push) Blocked by required conditions
Quick Checks / Unit tests for windows_amd64 (push) Blocked by required conditions
Quick Checks / Unit tests for linux_arm (push) Blocked by required conditions
Quick Checks / Unit tests for darwin_arm64 (push) Blocked by required conditions
Quick Checks / Unit tests for linux_arm64 (push) Blocked by required conditions
Quick Checks / Race Tests (push) Blocked by required conditions
Quick Checks / End-to-end Tests (push) Blocked by required conditions
Quick Checks / Code Consistency Checks (push) Blocked by required conditions
Quick Checks / License Checks (push) Waiting to run
Website checks / List files changed for pull request (push) Waiting to run
Website checks / Build (push) Blocked by required conditions
Website checks / Test Installation Instructions (push) Blocked by required conditions
Some checks are pending
build / Build for freebsd_386 (push) Waiting to run
build / Build for linux_386 (push) Waiting to run
build / Build for openbsd_386 (push) Waiting to run
build / Build for windows_386 (push) Waiting to run
build / Build for freebsd_amd64 (push) Waiting to run
build / Build for linux_amd64 (push) Waiting to run
build / Build for openbsd_amd64 (push) Waiting to run
build / Build for solaris_amd64 (push) Waiting to run
build / Build for windows_amd64 (push) Waiting to run
build / Build for freebsd_arm (push) Waiting to run
build / Build for linux_arm (push) Waiting to run
build / Build for linux_arm64 (push) Waiting to run
build / Build for darwin_amd64 (push) Waiting to run
build / Build for darwin_arm64 (push) Waiting to run
build / End-to-end Tests for linux_386 (push) Waiting to run
build / End-to-end Tests for windows_386 (push) Waiting to run
build / End-to-end Tests for darwin_amd64 (push) Waiting to run
build / End-to-end Tests for linux_amd64 (push) Waiting to run
build / End-to-end Tests for windows_amd64 (push) Waiting to run
Quick Checks / List files changed for pull request (push) Waiting to run
Quick Checks / Unit tests for linux_386 (push) Blocked by required conditions
Quick Checks / Unit tests for linux_amd64 (push) Blocked by required conditions
Quick Checks / Unit tests for windows_amd64 (push) Blocked by required conditions
Quick Checks / Unit tests for linux_arm (push) Blocked by required conditions
Quick Checks / Unit tests for darwin_arm64 (push) Blocked by required conditions
Quick Checks / Unit tests for linux_arm64 (push) Blocked by required conditions
Quick Checks / Race Tests (push) Blocked by required conditions
Quick Checks / End-to-end Tests (push) Blocked by required conditions
Quick Checks / Code Consistency Checks (push) Blocked by required conditions
Quick Checks / License Checks (push) Waiting to run
Website checks / List files changed for pull request (push) Waiting to run
Website checks / Build (push) Blocked by required conditions
Website checks / Test Installation Instructions (push) Blocked by required conditions
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
parent
d358f5743a
commit
ef97fd2b51
57 changed files with 2421 additions and 2342 deletions
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/backend"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/encryption"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/states/statemgr"
|
||||
|
|
@ -105,9 +106,9 @@ func TestLocalProvider(t *testing.T, b *Local, name string, schema providers.Pro
|
|||
}
|
||||
|
||||
// Set up our provider
|
||||
b.ContextOpts.Providers = map[addrs.Provider]providers.Factory{
|
||||
b.ContextOpts.Plugins = plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider(name): providers.FactoryFixed(p),
|
||||
}
|
||||
}, nil)
|
||||
|
||||
return p
|
||||
|
||||
|
|
|
|||
|
|
@ -1132,8 +1132,12 @@ func TestApply_shutdown(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
// Provider is started multiple times, plus it's left running after the schema call
|
||||
var stopOnce sync.Once
|
||||
p.StopFn = func() error {
|
||||
close(cancelled)
|
||||
stopOnce.Do(func() {
|
||||
close(cancelled)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/getmodules"
|
||||
"github.com/opentofu/opentofu/internal/getproviders"
|
||||
legacy "github.com/opentofu/opentofu/internal/legacy/tofu"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
|
|
@ -568,13 +569,17 @@ func (m *Meta) contextOpts(ctx context.Context) (*tofu.ContextOpts, error) {
|
|||
// and just work with what we've been given, thus allowing the tests
|
||||
// to provide mock providers and provisioners.
|
||||
if m.testingOverrides != nil {
|
||||
opts.Providers = m.testingOverrides.Providers
|
||||
opts.Provisioners = m.testingOverrides.Provisioners
|
||||
opts.Plugins = plugins.NewLibrary(
|
||||
m.testingOverrides.Providers,
|
||||
m.testingOverrides.Provisioners,
|
||||
)
|
||||
} else {
|
||||
var providerFactories map[addrs.Provider]providers.Factory
|
||||
providerFactories, err = m.providerFactories()
|
||||
opts.Providers = providerFactories
|
||||
opts.Provisioners = m.provisionerFactories()
|
||||
opts.Plugins = plugins.NewLibrary(
|
||||
providerFactories,
|
||||
m.provisionerFactories(),
|
||||
)
|
||||
}
|
||||
|
||||
opts.Meta = &tofu.ContextMeta{
|
||||
|
|
|
|||
|
|
@ -1520,8 +1520,12 @@ func TestPlan_shutdown(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
// Provider is started multiple times, plus it's left running after the schema call
|
||||
var stopOnce sync.Once
|
||||
p.StopFn = func() error {
|
||||
close(cancelled)
|
||||
stopOnce.Do(func() {
|
||||
close(cancelled)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/lang/eval"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
|
@ -80,8 +80,8 @@ type Provisioners interface {
|
|||
}
|
||||
|
||||
type newRuntimePlugins struct {
|
||||
providers map[addrs.Provider]providers.Factory
|
||||
provisioners map[string]provisioners.Factory
|
||||
providers plugins.ProviderManager
|
||||
provisioners plugins.ProvisionerManager
|
||||
|
||||
// unconfiguredInsts is all of the provider instances we've created for
|
||||
// unconfigured uses such as schema fetching and validation, which we
|
||||
|
|
@ -96,70 +96,41 @@ type newRuntimePlugins struct {
|
|||
var _ Providers = (*newRuntimePlugins)(nil)
|
||||
var _ Provisioners = (*newRuntimePlugins)(nil)
|
||||
|
||||
func NewRuntimePlugins(providers map[addrs.Provider]providers.Factory, provisioners map[string]provisioners.Factory) Plugins {
|
||||
func NewRuntimePluginsTemp(providerManager plugins.ProviderManager, provisionerManager plugins.ProvisionerManager) Plugins {
|
||||
return &newRuntimePlugins{
|
||||
providers: providers,
|
||||
provisioners: provisioners,
|
||||
providers: providerManager,
|
||||
provisioners: provisionerManager,
|
||||
unconfiguredInsts: map[addrs.Provider]providers.Unconfigured{},
|
||||
}
|
||||
}
|
||||
|
||||
func NewRuntimePlugins(plugins plugins.Library) Plugins {
|
||||
return &newRuntimePlugins{
|
||||
providers: plugins.NewProviderManager(),
|
||||
provisioners: plugins.NewProvisionerManager(),
|
||||
unconfiguredInsts: map[addrs.Provider]providers.Unconfigured{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewConfiguredProvider implements evalglue.Providers.
|
||||
func (n *newRuntimePlugins) NewConfiguredProvider(ctx context.Context, provider addrs.Provider, configVal cty.Value) (providers.Configured, tfdiags.Diagnostics) {
|
||||
inst, diags := n.newProviderInst(ctx, provider)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
unmarkedConfigVal, _ := configVal.UnmarkDeep()
|
||||
resp := inst.ConfigureProvider(ctx, providers.ConfigureProviderRequest{
|
||||
Config: unmarkedConfigVal,
|
||||
|
||||
// We aren't actually Terraform, so we'll just pretend to be a
|
||||
// Terraform version that has roughly the same functionality that
|
||||
// OpenTofu currently has, since providers are permitted to use this to
|
||||
// adapt their behavior for older versions of Terraform.
|
||||
TerraformVersion: "1.13.0",
|
||||
})
|
||||
diags = diags.Append(resp.Diagnostics)
|
||||
if resp.Diagnostics.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
return inst, diags
|
||||
return n.providers.NewConfiguredProvider(ctx, provider, configVal)
|
||||
}
|
||||
|
||||
// ProviderConfigSchema implements evalglue.Providers.
|
||||
func (n *newRuntimePlugins) ProviderConfigSchema(ctx context.Context, provider addrs.Provider) (*providers.Schema, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
inst, moreDiags := n.unconfiguredProviderInst(ctx, provider)
|
||||
diags = diags.Append(moreDiags)
|
||||
if moreDiags.HasErrors() {
|
||||
schema, diags := n.providers.GetProviderSchema(ctx, provider)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
resp := inst.GetProviderSchema(ctx)
|
||||
diags = diags.Append(resp.Diagnostics)
|
||||
if resp.Diagnostics.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
return &resp.Provider, diags
|
||||
return &schema.Provider, diags
|
||||
}
|
||||
|
||||
// ResourceTypeSchema implements evalglue.Providers.
|
||||
func (n *newRuntimePlugins) ResourceTypeSchema(ctx context.Context, provider addrs.Provider, mode addrs.ResourceMode, typeName string) (*providers.Schema, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
inst, moreDiags := n.unconfiguredProviderInst(ctx, provider)
|
||||
diags = diags.Append(moreDiags)
|
||||
if moreDiags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
resp := inst.GetProviderSchema(ctx)
|
||||
diags = diags.Append(resp.Diagnostics)
|
||||
if resp.Diagnostics.HasErrors() {
|
||||
schema, diags := n.providers.GetProviderSchema(ctx, provider)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
|
|
@ -171,11 +142,11 @@ func (n *newRuntimePlugins) ResourceTypeSchema(ctx context.Context, provider add
|
|||
var types map[string]providers.Schema
|
||||
switch mode {
|
||||
case addrs.ManagedResourceMode:
|
||||
types = resp.ResourceTypes
|
||||
types = schema.ResourceTypes
|
||||
case addrs.DataResourceMode:
|
||||
types = resp.DataSources
|
||||
types = schema.DataSources
|
||||
case addrs.EphemeralResourceMode:
|
||||
types = resp.EphemeralResources
|
||||
types = schema.EphemeralResources
|
||||
default:
|
||||
// We don't support any other modes, so we'll just treat these as
|
||||
// a request for a resource type that doesn't exist at all.
|
||||
|
|
@ -255,7 +226,7 @@ func (m *newRuntimePlugins) unconfiguredProviderInst(ctx context.Context, provid
|
|||
return running, nil
|
||||
}
|
||||
|
||||
inst, diags := m.newProviderInst(ctx, provider)
|
||||
inst, diags := m.providers.NewProvider(ctx, provider)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
|
@ -267,47 +238,6 @@ func (m *newRuntimePlugins) unconfiguredProviderInst(ctx context.Context, provid
|
|||
return inst, diags
|
||||
}
|
||||
|
||||
// newProviderInst creates a new instance of the given provider.
|
||||
//
|
||||
// The result is not retained anywhere inside the receiver. Each call to this
|
||||
// function returns a new object. A successful result is always an unconfigured
|
||||
// provider, but we return [providers.Interface] in case the caller would like
|
||||
// to subsequently configure the result before returning it as
|
||||
// [providers.Configured].
|
||||
//
|
||||
// If you intend to use the resulting instance only for "unconfigured"
|
||||
// operations like fetching schema, use
|
||||
// [newRuntimePlugins.unconfiguredProviderInst] instead to potentially reuse
|
||||
// an already-active instance of the same provider.
|
||||
func (m *newRuntimePlugins) newProviderInst(_ context.Context, provider addrs.Provider) (providers.Interface, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
factory, ok := m.providers[provider]
|
||||
if !ok {
|
||||
// FIXME: If this error remains reachable in the final version of this
|
||||
// code (i.e. if some caller isn't already guaranteeing that all
|
||||
// providers from the configuration and state are included here) then
|
||||
// we should make this error message more actionable.
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Provider unavailable",
|
||||
fmt.Sprintf("This configuration requires provider %q, but it isn't installed.", provider),
|
||||
))
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
inst, err := factory()
|
||||
if err != nil {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Provider failed to start",
|
||||
fmt.Sprintf("Failed to launch provider %q: %s.", provider, tfdiags.FormatError(err)),
|
||||
))
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
return inst, diags
|
||||
}
|
||||
|
||||
// ProvisionerConfigSchema implements evalglue.Provisioners.
|
||||
func (n *newRuntimePlugins) ProvisionerConfigSchema(ctx context.Context, typeName string) (*configschema.Block, tfdiags.Diagnostics) {
|
||||
// TODO: Implement this in terms of [newRuntimePlugins.provisioners].
|
||||
|
|
@ -328,13 +258,6 @@ func (n *newRuntimePlugins) Close(ctx context.Context) error {
|
|||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
|
||||
var errs error
|
||||
for addr, p := range n.unconfiguredInsts {
|
||||
err := p.Close(ctx)
|
||||
if err != nil {
|
||||
errs = errors.Join(errs, fmt.Errorf("closing provider %q: %w", addr, err))
|
||||
}
|
||||
}
|
||||
n.unconfiguredInsts = nil // discard all of the memoized instances
|
||||
return errs
|
||||
return errors.Join(n.providers.CloseAll(ctx), n.provisioners.CloseAll())
|
||||
}
|
||||
|
|
|
|||
21
internal/plugins/doc.go
Normal file
21
internal/plugins/doc.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) The OpenTofu Authors
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright (c) 2023 HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
// The plugins package abstracts away many of the details in managing provider and provisioner plugins.
|
||||
//
|
||||
// It's primary goal is to provide a library of plugins, who's instances can be managed in different concurrent
|
||||
// scopes. It also handles many of the complexities around correctly caching plugin schemas.
|
||||
//
|
||||
// This package was introduced to solve the following problems:
|
||||
// * De-duplicate common logic between the original tofu engine and the new engine implementation
|
||||
// * Re-use this common logic for backends as plugins / PSS
|
||||
// * Potentially allow plugins to be used by middleware/integrations/etc... (still in the design phase)
|
||||
// * Properly fix the global schema cache replacement
|
||||
// * Ensure that provider schema validation is actually called (heavily bugged before)
|
||||
//
|
||||
// It's current design intentions are that of a building block, and is not highly opinionated on abstracting
|
||||
// away the implementation details of plugins.
|
||||
|
||||
package plugins
|
||||
71
internal/plugins/library.go
Normal file
71
internal/plugins/library.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (c) The OpenTofu Authors
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright (c) 2023 HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
)
|
||||
|
||||
// Library represents a suite of provider and provisioner plugins. It does not expose
|
||||
// much functionality itself, instead serving as a starting point for the more complex
|
||||
// managers.
|
||||
type Library interface {
|
||||
NewProviderManager() ProviderManager
|
||||
NewProvisionerManager() ProvisionerManager
|
||||
|
||||
HasProvider(addr addrs.Provider) bool
|
||||
HasProvisioner(typ string) bool
|
||||
}
|
||||
|
||||
func NewLibrary(providerFactories ProviderFactories, provisionerFactories ProvisionerFactories) Library {
|
||||
return &library{
|
||||
providerFactories: providerFactories,
|
||||
providerSchemas: map[addrs.Provider]*providerSchemaEntry{},
|
||||
|
||||
provisionerFactories: provisionerFactories,
|
||||
provisionerSchemas: map[string]*provisionerSchemaEntry{},
|
||||
}
|
||||
}
|
||||
|
||||
// library is the default Library implementation, with included fields to facilitate
|
||||
// schema caching among managers.
|
||||
type library struct {
|
||||
providerSchemasLock sync.Mutex
|
||||
providerSchemas map[addrs.Provider]*providerSchemaEntry
|
||||
providerFactories ProviderFactories
|
||||
|
||||
provisionerSchemasLock sync.Mutex
|
||||
provisionerSchemas map[string]*provisionerSchemaEntry
|
||||
provisionerFactories ProvisionerFactories
|
||||
}
|
||||
|
||||
type providerSchemaEntry struct {
|
||||
sync.Mutex
|
||||
populated bool
|
||||
|
||||
schema providers.ProviderSchema
|
||||
diags tfdiags.Diagnostics
|
||||
}
|
||||
|
||||
type provisionerSchemaEntry struct {
|
||||
sync.Mutex
|
||||
populated bool
|
||||
|
||||
schema *configschema.Block
|
||||
err error
|
||||
}
|
||||
|
||||
func (l *library) HasProvider(addr addrs.Provider) bool {
|
||||
return l.providerFactories.HasProvider(addr)
|
||||
}
|
||||
func (l *library) HasProvisioner(typ string) bool {
|
||||
return l.provisionerFactories.HasProvisioner(typ)
|
||||
}
|
||||
238
internal/plugins/provider.go
Normal file
238
internal/plugins/provider.go
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
// Copyright (c) The OpenTofu Authors
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright (c) 2023 HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
"github.com/opentofu/opentofu/version"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
type ProviderFactories map[addrs.Provider]providers.Factory
|
||||
|
||||
func (p ProviderFactories) HasProvider(addr addrs.Provider) bool {
|
||||
_, ok := p[addr]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (p ProviderFactories) NewInstance(addr addrs.Provider) (providers.Interface, error) {
|
||||
f, ok := p[addr]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unavailable provider %q", addr)
|
||||
}
|
||||
|
||||
return f()
|
||||
}
|
||||
|
||||
// ProviderManager allows for spawning, tracking and management of provider instances.
|
||||
type ProviderManager interface {
|
||||
// HasProvider checks to see if the underlying library contains a given provider.
|
||||
HasProvider(addr addrs.Provider) bool
|
||||
|
||||
// GetProviderSchema returns a fully validated and cached provider schema. This should
|
||||
// always be preferred to accessing the schema directly from a provider.
|
||||
GetProviderSchema(ctx context.Context, addr addrs.Provider) (providers.ProviderSchema, tfdiags.Diagnostics)
|
||||
|
||||
// NewProvider starts and tracks a new provider instance of the given type.
|
||||
NewProvider(ctx context.Context, addr addrs.Provider) (providers.Interface, tfdiags.Diagnostics)
|
||||
// NewConfiguredProvider starts, configures, and tracks a new provider instance of the give type.
|
||||
NewConfiguredProvider(ctx context.Context, addr addrs.Provider, cfgVal cty.Value) (providers.Configured, tfdiags.Diagnostics)
|
||||
|
||||
// StopAll gracefully requests all tracked providers to stop.
|
||||
// See [providers.Unconfigured.Stop] for more information.
|
||||
StopAll(context.Context) error
|
||||
// CloseAll forcefully closes all tracked providers.
|
||||
// See [providers.Unconfigured.Close] for more information.
|
||||
// See cmd/tofu/main.go:plugin.CleanupClients for the fallback.
|
||||
CloseAll(context.Context) error
|
||||
// Shutdown locks the provider manager in a Shutdown state and calls CloseAll,
|
||||
// preventing any further usage of this object.
|
||||
Shutdown(context.Context) error
|
||||
}
|
||||
|
||||
type providerManager struct {
|
||||
*library
|
||||
|
||||
instancesLock sync.Mutex
|
||||
instances []providers.Configured
|
||||
|
||||
isShutdown atomic.Bool
|
||||
}
|
||||
|
||||
func (l *library) NewProviderManager() ProviderManager {
|
||||
return &providerManager{
|
||||
library: l,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *providerManager) HasProvider(addr addrs.Provider) bool {
|
||||
return p.providerFactories.HasProvider(addr)
|
||||
}
|
||||
|
||||
func (p *providerManager) GetProviderSchema(ctx context.Context, addr addrs.Provider) (providers.ProviderSchema, tfdiags.Diagnostics) {
|
||||
if p.isShutdown.Load() {
|
||||
// It's technically possible, but highly unlikely that a manager could be shutdown while fetching the schema
|
||||
// In that scenario, we will start and then stop the corresponding provider internally to this function and not
|
||||
// interfere with the set of known instances.
|
||||
return providers.ProviderSchema{}, tfdiags.Diagnostics{}.Append(fmt.Errorf("bug: unable to start provider %s, manager is shutdown", addr))
|
||||
}
|
||||
|
||||
// Coarse lock only for ensuring that a valid entry exists
|
||||
p.providerSchemasLock.Lock()
|
||||
entry, ok := p.providerSchemas[addr]
|
||||
if !ok {
|
||||
entry = &providerSchemaEntry{}
|
||||
p.providerSchemas[addr] = entry
|
||||
}
|
||||
// This lock is only for access to the map. We don't need to hold the lock when updating the entry
|
||||
// because we lock the individual entry for all access.
|
||||
// We don't defer unlock as the majority of the work of this function happens in updating the entry
|
||||
// and we want to release as soon as possible for multiple concurrent callers of different providers
|
||||
p.providerSchemasLock.Unlock()
|
||||
|
||||
entry.Lock()
|
||||
defer entry.Unlock()
|
||||
|
||||
if !entry.populated {
|
||||
log.Printf("[TRACE] plugins.providerManager Initializing provider %q to read its schema", addr)
|
||||
|
||||
provider, err := p.providerFactories.NewInstance(addr)
|
||||
if err != nil {
|
||||
// Might be a transient error. Don't memoize this result
|
||||
return providers.ProviderSchema{}, tfdiags.Diagnostics{}.Append(fmt.Errorf("failed to instantiate provider %q to obtain schema: %w", addr, err))
|
||||
}
|
||||
// TODO consider using the p.NewProvider(ctx, addr) call once we have a clear
|
||||
// .Close() call for all usages of the provider manager
|
||||
defer provider.Close(context.WithoutCancel(ctx))
|
||||
|
||||
entry.schema = provider.GetProviderSchema(ctx)
|
||||
entry.diags = entry.diags.Append(entry.schema.Diagnostics)
|
||||
entry.populated = true
|
||||
|
||||
if !entry.diags.HasErrors() {
|
||||
// Validate only if GetProviderSchema succeeded
|
||||
err := entry.schema.Validate(addr)
|
||||
entry.diags = entry.diags.Append(err)
|
||||
}
|
||||
}
|
||||
|
||||
return entry.schema, entry.diags
|
||||
}
|
||||
|
||||
func (p *providerManager) NewProvider(ctx context.Context, addr addrs.Provider) (providers.Interface, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
p.instancesLock.Lock()
|
||||
defer p.instancesLock.Unlock()
|
||||
if p.isShutdown.Load() {
|
||||
return nil, diags.Append(fmt.Errorf("bug: unable to start provider %s, manager is shutdown", addr))
|
||||
}
|
||||
|
||||
provider, err := p.providerFactories.NewInstance(addr)
|
||||
if err != nil {
|
||||
return nil, diags.Append(err)
|
||||
}
|
||||
|
||||
p.instances = append(p.instances, provider)
|
||||
|
||||
return provider, diags
|
||||
}
|
||||
|
||||
func (p *providerManager) NewConfiguredProvider(ctx context.Context, addr addrs.Provider, configVal cty.Value) (providers.Configured, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
p.instancesLock.Lock()
|
||||
defer p.instancesLock.Unlock()
|
||||
if p.isShutdown.Load() {
|
||||
return nil, diags.Append(fmt.Errorf("bug: unable to start provider %s, manager is shutdown", addr))
|
||||
}
|
||||
|
||||
provider, err := p.providerFactories.NewInstance(addr)
|
||||
if err != nil {
|
||||
return nil, diags.Append(err)
|
||||
}
|
||||
|
||||
p.instances = append(p.instances, provider)
|
||||
|
||||
// If our config value contains any marked values, ensure those are
|
||||
// stripped out before sending this to the provider
|
||||
unmarkedConfigVal, _ := configVal.UnmarkDeep()
|
||||
|
||||
// Allow the provider to validate and insert any defaults into the full
|
||||
// configuration.
|
||||
req := providers.ValidateProviderConfigRequest{
|
||||
Config: unmarkedConfigVal,
|
||||
}
|
||||
|
||||
// ValidateProviderConfig is only used for validation. We are intentionally
|
||||
// ignoring the PreparedConfig field to maintain existing behavior.
|
||||
validateResp := provider.ValidateProviderConfig(ctx, req)
|
||||
diags = diags.Append(validateResp.Diagnostics)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
// If the provider returns something different, log a warning to help
|
||||
// indicate to provider developers that the value is not used.
|
||||
preparedCfg := validateResp.PreparedConfig
|
||||
if preparedCfg != cty.NilVal && !preparedCfg.IsNull() && !preparedCfg.RawEquals(unmarkedConfigVal) {
|
||||
log.Printf("[WARN] ValidateProviderConfig from %q changed the config value, but that value is unused", addr)
|
||||
}
|
||||
|
||||
configResp := provider.ConfigureProvider(ctx, providers.ConfigureProviderRequest{
|
||||
// We aren't actually Terraform, so we'll just pretend to be a
|
||||
// Terraform version that has roughly the same functionality that
|
||||
// OpenTofu currently has, since providers are permitted to use this to
|
||||
// adapt their behavior for older versions of Terraform.
|
||||
TerraformVersion: version.VersionToImpersonateForProviders,
|
||||
Config: unmarkedConfigVal,
|
||||
})
|
||||
diags = diags.Append(configResp.Diagnostics)
|
||||
|
||||
return provider, diags
|
||||
}
|
||||
|
||||
func (p *providerManager) StopAll(ctx context.Context) error {
|
||||
p.instancesLock.Lock()
|
||||
defer p.instancesLock.Unlock()
|
||||
|
||||
var errs []error
|
||||
|
||||
for _, instance := range p.instances {
|
||||
errs = append(errs, instance.Stop(ctx))
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (p *providerManager) CloseAll(ctx context.Context) error {
|
||||
p.instancesLock.Lock()
|
||||
defer p.instancesLock.Unlock()
|
||||
|
||||
var errs []error
|
||||
|
||||
for _, instance := range p.instances {
|
||||
errs = append(errs, instance.Close(ctx))
|
||||
}
|
||||
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (p *providerManager) Shutdown(ctx context.Context) error {
|
||||
// Disable any further usage of this manager
|
||||
p.isShutdown.Store(true)
|
||||
|
||||
return p.CloseAll(ctx)
|
||||
}
|
||||
207
internal/plugins/provisioner.go
Normal file
207
internal/plugins/provisioner.go
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
// Copyright (c) The OpenTofu Authors
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright (c) 2023 HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
type ProvisionerFactories map[string]provisioners.Factory
|
||||
|
||||
func (p ProvisionerFactories) HasProvisioner(typ string) bool {
|
||||
_, ok := p[typ]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (p ProvisionerFactories) NewInstance(typ string) (provisioners.Interface, error) {
|
||||
f, ok := p[typ]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unavailable provisioner %q", typ)
|
||||
}
|
||||
|
||||
return f()
|
||||
}
|
||||
|
||||
// ProvisionerManager exposes provisioner functionality through functions, instead
|
||||
// of providing access to the provisioner instances themselves.
|
||||
type ProvisionerManager interface {
|
||||
// HasProvisioner checks to see if the underlying library contains a given provisioner.
|
||||
HasProvisioner(typ string) bool
|
||||
|
||||
// ProvisionerSchema is a caching wrapper for [provisioners.Interface.GetSchema]
|
||||
ProvisionerSchema(typ string) (*configschema.Block, error)
|
||||
// [provisioners.Interface.ValidateProvisionerConfig]
|
||||
ValidateProvisionerConfig(ctx context.Context, typ string, config cty.Value) tfdiags.Diagnostics
|
||||
// [provisioners.Interface.ProvisionResource]
|
||||
ProvisionResource(ctx context.Context, typ string, config cty.Value, connection cty.Value, output provisioners.UIOutput) tfdiags.Diagnostics
|
||||
|
||||
// StopAll gracefully requests all tracked provisioners to stop.
|
||||
// See [provisioners.Interface.Stop] for more information.
|
||||
StopAll() error
|
||||
// CloseAll forcefully closes all tracked provisioners.
|
||||
// See [provisioners.Interface.Close] for more information.
|
||||
// See cmd/tofu/main.go:plugin.CleanupClients for the fallback.
|
||||
CloseAll() error
|
||||
// Shutdown locks the provisioner manager in a Shutdown state and calls CloseAll,
|
||||
// preventing any further usage of this object.
|
||||
Shutdown() error
|
||||
}
|
||||
|
||||
type provisionerManager struct {
|
||||
*library
|
||||
|
||||
instancesLock sync.Mutex
|
||||
instances map[string]provisioners.Interface
|
||||
|
||||
isShutdown atomic.Bool
|
||||
}
|
||||
|
||||
func (l *library) NewProvisionerManager() ProvisionerManager {
|
||||
return &provisionerManager{
|
||||
library: l,
|
||||
instances: map[string]provisioners.Interface{},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *provisionerManager) HasProvisioner(typ string) bool {
|
||||
return p.provisionerFactories.HasProvisioner(typ)
|
||||
}
|
||||
|
||||
func (p *provisionerManager) provisioner(typ string) (provisioners.Interface, error) {
|
||||
p.instancesLock.Lock()
|
||||
defer p.instancesLock.Unlock()
|
||||
|
||||
if p.isShutdown.Load() {
|
||||
return nil, fmt.Errorf("bug: unable to start provisioner %s, manager is shutdown", typ)
|
||||
}
|
||||
|
||||
instance, ok := p.instances[typ]
|
||||
if !ok {
|
||||
var err error
|
||||
instance, err = p.provisionerFactories.NewInstance(typ)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.instances[typ] = instance
|
||||
}
|
||||
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
// ProvisionerSchema uses a temporary instance of the provisioner with the
|
||||
// given type name to obtain the schema for that provisioner's configuration.
|
||||
//
|
||||
// ProvisionerSchema memoizes results by provisioner type name, so it's fine
|
||||
// to repeatedly call this method with the same name if various different
|
||||
// parts of OpenTofu all need the same schema information.
|
||||
func (p *provisionerManager) ProvisionerSchema(typ string) (*configschema.Block, error) {
|
||||
// Coarse lock only for ensuring that a valid entry exists
|
||||
p.provisionerSchemasLock.Lock()
|
||||
entry, ok := p.provisionerSchemas[typ]
|
||||
if !ok {
|
||||
entry = &provisionerSchemaEntry{}
|
||||
p.provisionerSchemas[typ] = entry
|
||||
}
|
||||
// This lock is only for access to the map. We don't need to hold the lock when updating the entry
|
||||
// because we lock the individual entry for all access.
|
||||
// We don't defer unlock as the majority of the work of this function happens in updating the entry
|
||||
// and we want to release as soon as possible for multiple concurrent callers of different provisioners
|
||||
p.provisionerSchemasLock.Unlock()
|
||||
|
||||
entry.Lock()
|
||||
defer entry.Unlock()
|
||||
|
||||
if !entry.populated {
|
||||
log.Printf("[TRACE] Initializing provisioner %q to read its schema", typ)
|
||||
provisioner, err := p.provisionerFactories.NewInstance(typ)
|
||||
if err != nil {
|
||||
// Might be a transient error. Don't memoize this result
|
||||
return nil, fmt.Errorf("failed to instantiate provisioner %q to obtain schema: %w", typ, err)
|
||||
}
|
||||
// TODO consider using the p.provisioner(typ) call once we have a clear
|
||||
// .Close() call for all usages of the provisioner manager
|
||||
defer provisioner.Close()
|
||||
|
||||
resp := provisioner.GetSchema()
|
||||
|
||||
entry.populated = true
|
||||
entry.schema = resp.Provisioner
|
||||
if resp.Diagnostics.HasErrors() {
|
||||
entry.err = fmt.Errorf("failed to retrieve schema from provisioner %q: %w", typ, resp.Diagnostics.Err())
|
||||
}
|
||||
}
|
||||
|
||||
return entry.schema, entry.err
|
||||
}
|
||||
|
||||
func (p *provisionerManager) ValidateProvisionerConfig(ctx context.Context, typ string, config cty.Value) tfdiags.Diagnostics {
|
||||
provisioner, err := p.provisioner(typ)
|
||||
if err != nil {
|
||||
return tfdiags.Diagnostics{}.Append(fmt.Errorf("failed to instantiate provisioner %q to validate config: %w", typ, err))
|
||||
}
|
||||
return provisioner.ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{
|
||||
Config: config,
|
||||
}).Diagnostics
|
||||
}
|
||||
|
||||
func (p *provisionerManager) ProvisionResource(ctx context.Context, typ string, config cty.Value, connection cty.Value, output provisioners.UIOutput) tfdiags.Diagnostics {
|
||||
provisioner, err := p.provisioner(typ)
|
||||
if err != nil {
|
||||
return tfdiags.Diagnostics{}.Append(fmt.Errorf("failed to instantiate provisioner %q to provision resource: %w", typ, err))
|
||||
}
|
||||
return provisioner.ProvisionResource(provisioners.ProvisionResourceRequest{
|
||||
Config: config,
|
||||
Connection: connection,
|
||||
UIOutput: output,
|
||||
}).Diagnostics
|
||||
}
|
||||
|
||||
func (p *provisionerManager) StopAll() error {
|
||||
p.instancesLock.Lock()
|
||||
defer p.instancesLock.Unlock()
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
for name, prov := range p.instances {
|
||||
err := prov.Stop()
|
||||
if err != nil {
|
||||
diags = diags.Append(fmt.Errorf("provisioner.Stop %s: %w", name, err))
|
||||
}
|
||||
}
|
||||
return diags.Err()
|
||||
}
|
||||
|
||||
func (p *provisionerManager) CloseAll() error {
|
||||
p.instancesLock.Lock()
|
||||
defer p.instancesLock.Unlock()
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
for name, prov := range p.instances {
|
||||
err := prov.Close()
|
||||
if err != nil {
|
||||
diags = diags.Append(fmt.Errorf("provisioner.Close %s: %w", name, err))
|
||||
}
|
||||
}
|
||||
|
||||
clear(p.instances)
|
||||
|
||||
return diags.Err()
|
||||
}
|
||||
|
||||
func (p *provisionerManager) Shutdown() error {
|
||||
// Disable any further usage of this manager
|
||||
p.isShutdown.Store(true)
|
||||
|
||||
return p.CloseAll()
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/initwd"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tofu"
|
||||
|
|
@ -286,9 +287,9 @@ func testSession(t *testing.T, test testSessionTest) {
|
|||
|
||||
// Build the TF context
|
||||
ctx, diags := tofu.NewContext(&tofu.ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): providers.FactoryFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("failed to create context: %s", diags.Err())
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
)
|
||||
|
|
@ -107,9 +108,9 @@ func BenchmarkManyResourceInstances(b *testing.B) {
|
|||
},
|
||||
}
|
||||
tofuCtx := testContext2(b, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewBuiltInProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
// With this many resource instances we need a high concurrency limit
|
||||
// for the runtime to be in any way reasonable. In this case we're
|
||||
// going to set it so high that there is effectively no limit at all,
|
||||
|
|
@ -229,7 +230,7 @@ func BenchmarkManyModuleInstances(b *testing.B) {
|
|||
`,
|
||||
})
|
||||
tofuCtx := testContext2(b, &ContextOpts{
|
||||
Providers: nil, // no providers for this test
|
||||
Plugins: nil, // no providers for this test
|
||||
// With this many resource instances we need a high concurrency limit
|
||||
// for the runtime to be in any way reasonable. In this case we're
|
||||
// going to set it so high that there is effectively no limit at all,
|
||||
|
|
|
|||
|
|
@ -14,12 +14,10 @@ import (
|
|||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs"
|
||||
"github.com/opentofu/opentofu/internal/encryption"
|
||||
"github.com/opentofu/opentofu/internal/logging"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
)
|
||||
|
|
@ -40,12 +38,11 @@ const (
|
|||
// ContextOpts are the user-configurable options to create a context with
|
||||
// NewContext.
|
||||
type ContextOpts struct {
|
||||
Meta *ContextMeta
|
||||
Hooks []Hook
|
||||
Parallelism int
|
||||
Providers map[addrs.Provider]providers.Factory
|
||||
Provisioners map[string]provisioners.Factory
|
||||
Encryption encryption.Encryption
|
||||
Meta *ContextMeta
|
||||
Hooks []Hook
|
||||
Parallelism int
|
||||
Plugins plugins.Library
|
||||
Encryption encryption.Encryption
|
||||
|
||||
UIInput UIInput
|
||||
}
|
||||
|
|
@ -135,7 +132,7 @@ func NewContext(opts *ContextOpts) (*Context, tfdiags.Diagnostics) {
|
|||
par = 10
|
||||
}
|
||||
|
||||
plugins := newContextPlugins(opts.Providers, opts.Provisioners)
|
||||
plugins := newContextPlugins(opts.Plugins)
|
||||
|
||||
log.Printf("[TRACE] tofu.NewContext: complete")
|
||||
|
||||
|
|
@ -291,44 +288,16 @@ func (c *Context) watchStop(walker *ContextGraphWalker) (chan struct{}, <-chan s
|
|||
// If we're here, we're stopped, trigger the call.
|
||||
log.Printf("[TRACE] Context: requesting providers and provisioners to gracefully stop")
|
||||
|
||||
{
|
||||
// Copy the providers so that a misbehaved blocking Stop doesn't
|
||||
// completely hang OpenTofu.
|
||||
walker.providerLock.Lock()
|
||||
toStop := make([]providers.Interface, 0, len(walker.providerCache))
|
||||
for _, providerMap := range walker.providerCache {
|
||||
for _, provider := range providerMap {
|
||||
toStop = append(toStop, provider)
|
||||
}
|
||||
}
|
||||
defer walker.providerLock.Unlock()
|
||||
|
||||
for _, p := range toStop {
|
||||
// We ignore the error for now since there isn't any reasonable
|
||||
// action to take if there is an error here, since the stop is still
|
||||
// advisory: OpenTofu will exit once the graph node completes.
|
||||
// The providers.Interface API contract requires that the
|
||||
// context passed to Stop is never canceled and has no deadline.
|
||||
_ = p.Stop(context.WithoutCancel(context.TODO()))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Call stop on all the provisioners
|
||||
walker.provisionerLock.Lock()
|
||||
ps := make([]provisioners.Interface, 0, len(walker.provisionerCache))
|
||||
for _, p := range walker.provisionerCache {
|
||||
ps = append(ps, p)
|
||||
}
|
||||
defer walker.provisionerLock.Unlock()
|
||||
|
||||
for _, p := range ps {
|
||||
// We ignore the error for now since there isn't any reasonable
|
||||
// action to take if there is an error here, since the stop is still
|
||||
// advisory: OpenTofu will exit once the graph node completes.
|
||||
_ = p.Stop()
|
||||
}
|
||||
}
|
||||
// We ignore the error for now since there isn't any reasonable
|
||||
// action to take if there is an error here, since the stop is still
|
||||
// advisory: OpenTofu will exit once the graph node completes.
|
||||
// The providers.Interface API contract requires that the
|
||||
// context passed to Stop is never canceled and has no deadline.
|
||||
_ = walker.Context.plugins.providers.StopAll(context.WithoutCancel(context.TODO()))
|
||||
// We ignore the error for now since there isn't any reasonable
|
||||
// action to take if there is an error here, since the stop is still
|
||||
// advisory: OpenTofu will exit once the graph node completes.
|
||||
_ = walker.Context.plugins.provisioners.StopAll()
|
||||
}()
|
||||
|
||||
return stop, wait
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/encryption"
|
||||
"github.com/opentofu/opentofu/internal/lang/marks"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/states/statefile"
|
||||
|
|
@ -72,9 +73,9 @@ func TestContext2Apply_createBeforeDestroy_deposedKeyPreApply(t *testing.T) {
|
|||
hook := new(MockHook)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Hooks: []Hook{hook},
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, DefaultPlanOpts)
|
||||
|
|
@ -159,9 +160,9 @@ func TestContext2Apply_createBeforeDestroy_dependsNonCBDUpdate(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, DefaultPlanOpts)
|
||||
|
|
@ -250,7 +251,7 @@ output "data" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), DefaultPlanOpts)
|
||||
|
|
@ -265,7 +266,7 @@ output "data" {
|
|||
|
||||
// now destroy the whole thing
|
||||
ctx = testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags = ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -335,9 +336,9 @@ resource "test_instance" "a" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, DefaultPlanOpts)
|
||||
|
|
@ -427,9 +428,9 @@ resource "aws_instance" "bin" {
|
|||
p := testProvider("aws")
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, DefaultPlanOpts)
|
||||
|
|
@ -531,9 +532,9 @@ resource "test_resource" "b" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, SimplePlanOpts(plans.NormalMode, testInputValuesUnset(m.Module.Variables)))
|
||||
|
|
@ -572,9 +573,9 @@ output "out" {
|
|||
p := simpleMockProvider()
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), DefaultPlanOpts)
|
||||
|
|
@ -676,9 +677,9 @@ func TestContext2Apply_sensitiveInsideUnknown(t *testing.T) {
|
|||
}
|
||||
|
||||
tofuCtx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.MustParseProviderSourceString("example.com/foo/test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := tofuCtx.Plan(t.Context(), m, states.NewState(), SimplePlanOpts(plans.NormalMode, nil))
|
||||
|
|
@ -747,9 +748,9 @@ resource "test_object" "y" {
|
|||
p := simpleMockProvider()
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), SimplePlanOpts(plans.NormalMode, testInputValuesUnset(m.Module.Variables)))
|
||||
|
|
@ -801,9 +802,9 @@ resource "test_object" "x" {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -857,9 +858,9 @@ resource "test_object" "x" {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -938,9 +939,9 @@ resource "test_object" "s" {
|
|||
p := simpleMockProvider()
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), DefaultPlanOpts)
|
||||
|
|
@ -988,9 +989,9 @@ resource "test_object" "s" {
|
|||
p := simpleMockProvider()
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), DefaultPlanOpts)
|
||||
|
|
@ -1044,9 +1045,9 @@ resource "test_object" "b" {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -1120,9 +1121,9 @@ resource "test_resource" "c" {
|
|||
return resp
|
||||
}
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
t.Run("condition pass", func(t *testing.T) {
|
||||
|
|
@ -1430,9 +1431,9 @@ func TestContext2Apply_resourceConditionApplyTimeFail(t *testing.T) {
|
|||
return resp
|
||||
}
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
instA := mustResourceInstanceAddr("test_resource.a")
|
||||
instB := mustResourceInstanceAddr("test_resource.b")
|
||||
|
|
@ -1626,10 +1627,10 @@ output "out" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(testProvider),
|
||||
addrs.NewDefaultProvider("other"): testProviderFuncFixed(otherProvider),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
opts := SimplePlanOpts(plans.NormalMode, testInputValuesUnset(m.Module.Variables))
|
||||
|
|
@ -1748,9 +1749,9 @@ resource "test_object" "x" {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -1799,9 +1800,9 @@ resource "test_object" "y" {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
opts := SimplePlanOpts(plans.NormalMode, nil)
|
||||
|
|
@ -1880,9 +1881,9 @@ output "data" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
// apply the state
|
||||
|
|
@ -1956,9 +1957,9 @@ output "from_resource" {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
opts := SimplePlanOpts(plans.DestroyMode, nil)
|
||||
|
|
@ -2013,9 +2014,9 @@ output "from_resource" {
|
|||
mod.SetOutputValue("from_resource", cty.StringVal("wrong val"), false, "")
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
opts := SimplePlanOpts(plans.RefreshOnlyMode, nil)
|
||||
|
|
@ -2083,9 +2084,9 @@ resource "test_object" "y" {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
opts := SimplePlanOpts(plans.NormalMode, nil)
|
||||
|
|
@ -2118,9 +2119,9 @@ resource "test_object" "y" {
|
|||
func TestContext2Apply_preconditionErrorMessageRef(t *testing.T) {
|
||||
p := testProvider("test")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
m := testModuleInline(t, map[string]string{
|
||||
|
|
@ -2165,9 +2166,9 @@ output "a" {
|
|||
func TestContext2Apply_destroyNullModuleOutput(t *testing.T) {
|
||||
p := testProvider("test")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
m := testModuleInline(t, map[string]string{
|
||||
|
|
@ -2272,9 +2273,9 @@ output "resources" {
|
|||
},
|
||||
})
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
Mode: plans.NormalMode,
|
||||
|
|
@ -2359,9 +2360,9 @@ resource "test_resource" "b" {
|
|||
}
|
||||
}
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
Mode: plans.NormalMode,
|
||||
|
|
@ -2377,10 +2378,10 @@ func TestContext2Apply_destroyUnusedModuleProvider(t *testing.T) {
|
|||
unusedProvider := testProvider("unused")
|
||||
testProvider := testProvider("test")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(testProvider),
|
||||
addrs.NewDefaultProvider("unused"): testProviderFuncFixed(unusedProvider),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
unusedProvider.ConfigureProviderFn = func(req providers.ConfigureProviderRequest) (resp providers.ConfigureProviderResponse) {
|
||||
|
|
@ -2462,9 +2463,9 @@ import {
|
|||
hook := new(MockHook)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Hooks: []Hook{hook},
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
Mode: plans.NormalMode,
|
||||
|
|
@ -2504,9 +2505,9 @@ locals {
|
|||
|
||||
p := simpleMockProvider()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), nil)
|
||||
|
|
@ -2542,9 +2543,9 @@ locals {
|
|||
|
||||
p := simpleMockProvider()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -2606,9 +2607,9 @@ func TestContext2Apply_forgetOrphanAndDeposed(t *testing.T) {
|
|||
addrs.NoKey,
|
||||
)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.PlanResourceChangeFn = testDiffFn
|
||||
|
|
@ -2675,9 +2676,9 @@ func TestContext2Apply_forgetOrphanAndDeposedWithDynamicProvider(t *testing.T) {
|
|||
addrs.StringKey("a"),
|
||||
)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.PlanResourceChangeFn = testDiffFn
|
||||
|
|
@ -2864,9 +2865,9 @@ func TestContext2Apply_providerExpandWithTargetOrExclude(t *testing.T) {
|
|||
`,
|
||||
})
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewBuiltInProvider("mock"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, normalPlanOpts)
|
||||
assertNoErrors(t, diags)
|
||||
|
|
@ -2932,9 +2933,9 @@ func TestContext2Apply_providerExpandWithTargetOrExclude(t *testing.T) {
|
|||
`,
|
||||
})
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewBuiltInProvider("mock"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, makeStep2PlanOpts(plans.NormalMode))
|
||||
assertNoErrors(t, diags)
|
||||
|
|
@ -3005,9 +3006,9 @@ func TestContext2Apply_providerExpandWithTargetOrExclude(t *testing.T) {
|
|||
`,
|
||||
})
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewBuiltInProvider("mock"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, normalPlanOpts)
|
||||
assertNoErrors(t, diags)
|
||||
|
|
@ -3069,9 +3070,9 @@ func TestContext2Apply_moduleProviderAliasExcludes(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -3109,9 +3110,9 @@ func TestContext2Apply_moduleProviderAliasExcludesNonExistent(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -3149,9 +3150,9 @@ func TestContext2Apply_moduleExclude(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -3185,9 +3186,9 @@ func TestContext2Apply_moduleExcludeDependent(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -3216,9 +3217,9 @@ func TestContext2Apply_moduleExcludeNonExistent(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -3267,9 +3268,9 @@ func TestContext2Apply_destroyExcludedNonExistentWithModuleVariableAndCount(t *t
|
|||
var state *states.State
|
||||
{
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
// First plan and apply a create operation
|
||||
|
|
@ -3284,9 +3285,9 @@ func TestContext2Apply_destroyExcludedNonExistentWithModuleVariableAndCount(t *t
|
|||
|
||||
{
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -3356,9 +3357,9 @@ func TestContext2Apply_destroyExcludedWithModuleVariableAndCount(t *testing.T) {
|
|||
var state *states.State
|
||||
{
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
// First plan and apply a create operation
|
||||
|
|
@ -3373,9 +3374,9 @@ func TestContext2Apply_destroyExcludedWithModuleVariableAndCount(t *testing.T) {
|
|||
|
||||
{
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -3428,9 +3429,9 @@ func TestContext2Apply_excluded(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -3468,9 +3469,9 @@ func TestContext2Apply_excludedCount(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -3510,9 +3511,9 @@ func TestContext2Apply_excludedCountIndex(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -3562,9 +3563,9 @@ func TestContext2Apply_excludedDestroy(t *testing.T) {
|
|||
var state *states.State
|
||||
{
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
// First plan and apply a create operation
|
||||
|
|
@ -3583,9 +3584,9 @@ func TestContext2Apply_excludedDestroy(t *testing.T) {
|
|||
|
||||
{
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -3626,9 +3627,9 @@ func TestContext2Apply_excludedDestroyDependent(t *testing.T) {
|
|||
var state *states.State
|
||||
{
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
// First plan and apply a create operation
|
||||
|
|
@ -3647,9 +3648,9 @@ func TestContext2Apply_excludedDestroyDependent(t *testing.T) {
|
|||
|
||||
{
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -3735,9 +3736,9 @@ func TestContext2Apply_excludedDestroyCountDeps(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -3813,9 +3814,9 @@ func TestContext2Apply_excludedDependentDestroyCountDeps(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -3897,9 +3898,9 @@ func TestContext2Apply_excludedDestroyModule(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -3979,9 +3980,9 @@ func TestContext2Apply_excludedDestroyCountIndex(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -4018,9 +4019,9 @@ func TestContext2Apply_excludedModule(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -4061,9 +4062,9 @@ func TestContext2Apply_excludedModuleResourceDep(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -4096,9 +4097,9 @@ func TestContext2Apply_excludedResourceDependentOnModule(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -4134,9 +4135,9 @@ func TestContext2Apply_excludedModuleDep(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -4170,9 +4171,9 @@ func TestContext2Apply_excludedModuleUnrelatedOutputs(t *testing.T) {
|
|||
state := states.NewState()
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -4217,9 +4218,9 @@ func TestContext2Apply_excludedModuleResource(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -4277,9 +4278,9 @@ func TestContext2Apply_excludedResourceOrphanModule(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -4330,9 +4331,9 @@ func TestContext2Apply_excludedOrphanModule(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -4381,9 +4382,9 @@ func TestContext2Apply_excludedWithTaintedInState(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{
|
||||
|
|
@ -4404,9 +4405,9 @@ func TestContext2Apply_excludedWithTaintedInState(t *testing.T) {
|
|||
t.Fatalf("failed to round-trip through planfile: %s", err)
|
||||
}
|
||||
|
||||
ctxOpts.Providers = map[addrs.Provider]providers.Factory{
|
||||
ctxOpts.Plugins = plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
}
|
||||
}, nil)
|
||||
|
||||
ctx, diags = NewContext(ctxOpts)
|
||||
if diags.HasErrors() {
|
||||
|
|
@ -4439,9 +4440,9 @@ func TestContext2Apply_excludedModuleRecursive(t *testing.T) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{
|
||||
|
|
@ -4561,7 +4562,7 @@ data "test_data_source" "b_direct" {
|
|||
apply := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
t.Helper()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, DefaultPlanOpts)
|
||||
|
|
@ -4574,7 +4575,7 @@ data "test_data_source" "b_direct" {
|
|||
|
||||
destroy := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -4790,7 +4791,7 @@ data "test_data_source" "b" {
|
|||
apply := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
t.Helper()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, DefaultPlanOpts)
|
||||
|
|
@ -4803,7 +4804,7 @@ data "test_data_source" "b" {
|
|||
|
||||
destroy := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5020,7 +5021,7 @@ variable "other_var" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), valid, nil, &PlanOpts{
|
||||
|
|
@ -5107,7 +5108,7 @@ variable "res_data" {
|
|||
|
||||
apply := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5123,7 +5124,7 @@ variable "res_data" {
|
|||
|
||||
destroy := func(t *testing.T, m *configs.Config, prevState *states.State) tfdiags.Diagnostics {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5408,9 +5409,9 @@ module "modfe" {
|
|||
test := test
|
||||
t.Run(name, func(t *testing.T) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
mod := testModuleInline(t, test.module)
|
||||
|
|
@ -5528,7 +5529,7 @@ check "http_check" {
|
|||
|
||||
apply := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5543,7 +5544,7 @@ check "http_check" {
|
|||
|
||||
destroy := func(t *testing.T, m *configs.Config, prevState *states.State) tfdiags.Diagnostics {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5615,7 +5616,7 @@ check "http_check" {
|
|||
|
||||
apply := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5630,7 +5631,7 @@ check "http_check" {
|
|||
|
||||
destroy := func(t *testing.T, m *configs.Config, prevState *states.State) tfdiags.Diagnostics {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5696,7 +5697,7 @@ check "http_check" {
|
|||
|
||||
apply := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5711,7 +5712,7 @@ check "http_check" {
|
|||
|
||||
destroy := func(t *testing.T, m *configs.Config, prevState *states.State) tfdiags.Diagnostics {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -5770,8 +5771,8 @@ ephemeral "test_ephemeral_resource" "a" {
|
|||
h := &testHook{}
|
||||
apply := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Hooks: []Hook{h},
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
Hooks: []Hook{h},
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
@ -6343,9 +6344,9 @@ func TestContext2Apply_enabledForResource(t *testing.T) {
|
|||
}
|
||||
}
|
||||
tfCtx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
resourceInstAddr := addrs.Resource{
|
||||
Mode: addrs.ManagedResourceMode,
|
||||
|
|
@ -6481,7 +6482,7 @@ func TestContext2Apply_enabledForModule(t *testing.T) {
|
|||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(provider),
|
||||
}
|
||||
tfCtx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
})
|
||||
|
||||
resourceInstAddr := mustResourceInstanceAddr(`module.mod1.test_instance.a`)
|
||||
|
|
@ -6659,9 +6660,9 @@ resource "test_resource" "res" {
|
|||
}
|
||||
}
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.MustParseProviderSourceString("example.com/foo/test"): testProviderFuncFixed(&p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
assertState := func(t *testing.T, s *states.State) {
|
||||
|
|
@ -6921,8 +6922,8 @@ func TestContext2Apply_ephemeralInModuleWithExpansion(t *testing.T) {
|
|||
h := &testHook{}
|
||||
apply := func(t *testing.T, m *configs.Config, prevState *states.State) (*states.State, tfdiags.Diagnostics) {
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: ps,
|
||||
Hooks: []Hook{h},
|
||||
Plugins: plugins.NewLibrary(ps, nil),
|
||||
Hooks: []Hook{h},
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, prevState, &PlanOpts{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/checks"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -714,9 +715,9 @@ check "error" {
|
|||
t.Run(name, func(t *testing.T) {
|
||||
configs := testModuleInline(t, test.configs)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider(test.provider.Meta.(string)): testProviderFuncFixed(test.provider),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
initialState := states.NewState()
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
|
@ -55,9 +56,9 @@ func TestContextEval(t *testing.T) {
|
|||
m := testModule(t, "eval-context-basic")
|
||||
p := testProvider("test")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
scope, diags := ctx.Eval(context.Background(), m, states.NewState(), addrs.RootModuleInstance, &EvalOpts{
|
||||
|
|
@ -124,9 +125,9 @@ output "out" {
|
|||
|
||||
p := simpleMockProvider()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
_, diags := ctx.Eval(context.Background(), m, states.NewState(), addrs.RootModuleInstance, &EvalOpts{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
|
@ -30,8 +31,10 @@ type contextTestFixture struct {
|
|||
// _shallow_ modifications to the options as needed.
|
||||
func (f *contextTestFixture) ContextOpts() *ContextOpts {
|
||||
return &ContextOpts{
|
||||
Providers: f.Providers,
|
||||
Provisioners: f.Provisioners,
|
||||
Plugins: plugins.NewLibrary(
|
||||
f.Providers,
|
||||
f.Provisioners,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/lang/marks"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
|
@ -357,9 +358,9 @@ variable "obfmod" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -438,9 +439,9 @@ variable "obfmod" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -523,9 +524,9 @@ variable "obfmod" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -615,9 +616,9 @@ variable "obfmod" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
_, diags := ctx.Plan(context.Background(), m, nil, nil)
|
||||
|
|
@ -699,9 +700,9 @@ variable "obfmod" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -791,9 +792,9 @@ variable "value" { }
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import (
|
|||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -28,9 +29,9 @@ func TestContextImport_basic(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "import-provider")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -81,9 +82,9 @@ resource "aws_instance" "foo" {
|
|||
`})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -243,9 +244,9 @@ func TestContextImport_multiInstanceProviderConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewBuiltInProvider("test"): providerFactory,
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
existingInstanceKey := addrs.StringKey("foo")
|
||||
|
|
@ -320,9 +321,9 @@ resource "aws_instance" "foo" {
|
|||
`})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -382,9 +383,9 @@ func TestContextImport_collision(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "import-provider")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state := states.BuildState(func(s *states.SyncState) {
|
||||
|
|
@ -460,9 +461,9 @@ func TestContextImport_missingType(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Import(context.Background(), m, states.NewState(), &ImportOpts{
|
||||
|
|
@ -513,9 +514,9 @@ func TestContextImport_moduleProvider(t *testing.T) {
|
|||
|
||||
m := testModule(t, "import-provider")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Import(context.Background(), m, states.NewState(), &ImportOpts{
|
||||
|
|
@ -550,9 +551,9 @@ func TestContextImport_providerModule(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "import-module")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -617,9 +618,9 @@ func TestContextImport_providerConfig(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, test.module)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -678,10 +679,10 @@ func TestContextImport_providerConfigResources(t *testing.T) {
|
|||
pTest := testProvider("test")
|
||||
m := testModule(t, "import-provider-resources")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(pTest),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -736,9 +737,9 @@ data "aws_data_source" "bar" {
|
|||
`})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -799,9 +800,9 @@ func TestContextImport_refreshNil(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "import-provider")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -848,9 +849,9 @@ func TestContextImport_module(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "import-module")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -891,9 +892,9 @@ func TestContextImport_moduleDepth2(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "import-module")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -934,9 +935,9 @@ func TestContextImport_moduleDiff(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "import-module")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
@ -1015,9 +1016,9 @@ func TestContextImport_multiState(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Import(context.Background(), m, states.NewState(), &ImportOpts{
|
||||
|
|
@ -1091,9 +1092,9 @@ func TestContextImport_multiStateSame(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Import(context.Background(), m, states.NewState(), &ImportOpts{
|
||||
|
|
@ -1187,9 +1188,9 @@ resource "test_resource" "unused" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Import(context.Background(), m, states.NewState(), &ImportOpts{
|
||||
|
|
@ -1259,9 +1260,9 @@ resource "test_resource" "test" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Import(context.Background(), m, states.NewState(), &ImportOpts{
|
||||
|
|
@ -1295,9 +1296,9 @@ func TestContextImport_33572(t *testing.T) {
|
|||
m := testModule(t, "issue-33572")
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
)
|
||||
|
|
@ -79,11 +80,11 @@ func TestContext2Input_provider(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(awsp),
|
||||
addrs.NewDefaultProvider("cloudflare"): testProviderFuncFixed(cfp),
|
||||
addrs.NewDefaultProvider("azurerm"): testProviderFuncFixed(azp),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: inp,
|
||||
})
|
||||
|
||||
|
|
@ -182,11 +183,11 @@ func TestContext2Input_providerMulti(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): func() (providers.Interface, error) {
|
||||
return providerFactory()
|
||||
},
|
||||
},
|
||||
}, nil),
|
||||
UIInput: inp,
|
||||
})
|
||||
|
||||
|
|
@ -226,9 +227,9 @@ func TestContext2Input_providerOnce(t *testing.T) {
|
|||
m := testModule(t, "input-provider-once")
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
if diags := ctx.Input(context.Background(), m, InputModeStd); diags.HasErrors() {
|
||||
|
|
@ -262,9 +263,9 @@ func TestContext2Input_providerOnly(t *testing.T) {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: input,
|
||||
})
|
||||
|
||||
|
|
@ -322,9 +323,9 @@ func TestContext2Input_providerVars(t *testing.T) {
|
|||
m := testModule(t, "input-provider-with-vars")
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: input,
|
||||
})
|
||||
|
||||
|
|
@ -366,9 +367,9 @@ func TestContext2Input_providerVarsModuleInherit(t *testing.T) {
|
|||
m := testModule(t, "input-provider-with-vars-and-module")
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: input,
|
||||
})
|
||||
|
||||
|
|
@ -383,9 +384,9 @@ func TestContext2Input_submoduleTriggersInvalidCount(t *testing.T) {
|
|||
m := testModule(t, "input-submodule-count")
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: input,
|
||||
})
|
||||
|
||||
|
|
@ -441,9 +442,9 @@ func TestContext2Input_dataSourceRequiresRefresh(t *testing.T) {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("null"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: input,
|
||||
})
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -7,116 +7,48 @@ package tofu
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
)
|
||||
|
||||
// contextPlugins represents a library of available plugins (providers and
|
||||
// provisioners) which we assume will all be used with the same
|
||||
// tofu.Context, and thus it'll be safe to cache certain information
|
||||
// about the providers for performance reasons.
|
||||
type contextPlugins struct {
|
||||
providerFactories map[addrs.Provider]providers.Factory
|
||||
provisionerFactories map[string]provisioners.Factory
|
||||
|
||||
providerSchemasLock sync.Mutex
|
||||
providerSchemas map[addrs.Provider]providerSchemaEntry
|
||||
provisionerSchemasLock sync.Mutex
|
||||
provisionerSchemas map[string]provisionerSchemaEntry
|
||||
providers plugins.ProviderManager
|
||||
provisioners plugins.ProvisionerManager
|
||||
}
|
||||
|
||||
type providerSchemaEntry func() (providers.ProviderSchema, error)
|
||||
type provisionerSchemaEntry func() (*configschema.Block, error)
|
||||
|
||||
func newContextPlugins(providerFactories map[addrs.Provider]providers.Factory, provisionerFactories map[string]provisioners.Factory) *contextPlugins {
|
||||
func newContextPlugins(library plugins.Library) *contextPlugins {
|
||||
if library == nil {
|
||||
// We are in a *_test.go that should be fixed
|
||||
library = plugins.NewLibrary(nil, nil)
|
||||
}
|
||||
return &contextPlugins{
|
||||
providerFactories: providerFactories,
|
||||
provisionerFactories: provisionerFactories,
|
||||
|
||||
providerSchemas: map[addrs.Provider]providerSchemaEntry{},
|
||||
provisionerSchemas: map[string]provisionerSchemaEntry{},
|
||||
providers: library.NewProviderManager(),
|
||||
provisioners: library.NewProvisionerManager(),
|
||||
}
|
||||
}
|
||||
|
||||
func (cp *contextPlugins) HasProvider(addr addrs.Provider) bool {
|
||||
_, ok := cp.providerFactories[addr]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (cp *contextPlugins) NewProviderInstance(addr addrs.Provider) (providers.Interface, error) {
|
||||
f, ok := cp.providerFactories[addr]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unavailable provider %q", addr.String())
|
||||
}
|
||||
|
||||
return f()
|
||||
|
||||
return cp.providers.HasProvider(addr)
|
||||
}
|
||||
|
||||
func (cp *contextPlugins) HasProvisioner(typ string) bool {
|
||||
_, ok := cp.provisionerFactories[typ]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (cp *contextPlugins) NewProvisionerInstance(typ string) (provisioners.Interface, error) {
|
||||
f, ok := cp.provisionerFactories[typ]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unavailable provisioner %q", typ)
|
||||
}
|
||||
|
||||
return f()
|
||||
}
|
||||
|
||||
// ProviderSchema uses a temporary instance of the provider with the given
|
||||
// address to obtain the full schema for all aspects of that provider.
|
||||
//
|
||||
// ProviderSchema memoizes results by unique provider address, so it's fine
|
||||
// to repeatedly call this method with the same address if various different
|
||||
// parts of OpenTofu all need the same schema information.
|
||||
func (cp *contextPlugins) ProviderSchema(ctx context.Context, addr addrs.Provider) (providers.ProviderSchema, error) {
|
||||
// Coarse lock only for ensuring that a valid entry exists
|
||||
cp.providerSchemasLock.Lock()
|
||||
entry, ok := cp.providerSchemas[addr]
|
||||
if !ok {
|
||||
entry = sync.OnceValues(func() (providers.ProviderSchema, error) {
|
||||
log.Printf("[TRACE] tofu.contextPlugins: Initializing provider %q to read its schema", addr)
|
||||
provider, err := cp.NewProviderInstance(addr)
|
||||
if err != nil {
|
||||
return providers.ProviderSchema{}, fmt.Errorf("failed to instantiate provider %q to obtain schema: %w", addr, err)
|
||||
}
|
||||
defer provider.Close(ctx)
|
||||
|
||||
schema := provider.GetProviderSchema(ctx)
|
||||
return schema, schema.Validate(addr)
|
||||
})
|
||||
cp.providerSchemas[addr] = entry
|
||||
}
|
||||
// This lock is only for access to the map. We don't need to hold the lock when calling
|
||||
// "entry" because [sync.OnceValues] handles synchronization itself.
|
||||
// We don't defer unlock as the majority of the work of this function happens in calling "entry"
|
||||
// and we want to release as soon as possible for multiple concurrent callers of different providers
|
||||
cp.providerSchemasLock.Unlock()
|
||||
|
||||
return entry()
|
||||
return cp.provisioners.HasProvisioner(typ)
|
||||
}
|
||||
|
||||
// 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(ctx context.Context, providerAddr addrs.Provider) (*configschema.Block, error) {
|
||||
providerSchema, err := cp.ProviderSchema(ctx, providerAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (cp *contextPlugins) ProviderConfigSchema(ctx context.Context, providerAddr addrs.Provider) (*configschema.Block, tfdiags.Diagnostics) {
|
||||
providerSchema, diags := cp.providers.GetProviderSchema(ctx, providerAddr)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
return providerSchema.Provider.Block, nil
|
||||
return providerSchema.Provider.Block, diags
|
||||
}
|
||||
|
||||
// ResourceTypeSchema is a helper wrapper around ProviderSchema which first
|
||||
|
|
@ -130,14 +62,14 @@ func (cp *contextPlugins) ProviderConfigSchema(ctx context.Context, providerAddr
|
|||
// 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(ctx context.Context, providerAddr addrs.Provider, resourceMode addrs.ResourceMode, resourceType string) (*configschema.Block, uint64, error) {
|
||||
providerSchema, err := cp.ProviderSchema(ctx, providerAddr)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
func (cp *contextPlugins) ResourceTypeSchema(ctx context.Context, providerAddr addrs.Provider, resourceMode addrs.ResourceMode, resourceType string) (*configschema.Block, uint64, tfdiags.Diagnostics) {
|
||||
providerSchema, diags := cp.providers.GetProviderSchema(ctx, providerAddr)
|
||||
if diags.HasErrors() {
|
||||
return nil, 0, diags
|
||||
}
|
||||
|
||||
schema, version := providerSchema.SchemaForResourceType(resourceMode, resourceType)
|
||||
return schema, version, nil
|
||||
return schema, version, diags
|
||||
}
|
||||
|
||||
// ProvisionerSchema uses a temporary instance of the provisioner with the
|
||||
|
|
@ -147,31 +79,5 @@ func (cp *contextPlugins) ResourceTypeSchema(ctx context.Context, providerAddr a
|
|||
// to repeatedly call this method with the same name if various different
|
||||
// parts of OpenTofu all need the same schema information.
|
||||
func (cp *contextPlugins) ProvisionerSchema(addr string) (*configschema.Block, error) {
|
||||
// Coarse lock only for ensuring that a valid entry exists
|
||||
cp.provisionerSchemasLock.Lock()
|
||||
entry, ok := cp.provisionerSchemas[addr]
|
||||
if !ok {
|
||||
entry = sync.OnceValues(func() (*configschema.Block, error) {
|
||||
log.Printf("[TRACE] tofu.contextPlugins: Initializing provisioner %q to read its schema", addr)
|
||||
provisioner, err := cp.NewProvisionerInstance(addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to instantiate provisioner %q to obtain schema: %w", addr, err)
|
||||
}
|
||||
defer provisioner.Close()
|
||||
|
||||
resp := provisioner.GetSchema()
|
||||
if resp.Diagnostics.HasErrors() {
|
||||
return nil, fmt.Errorf("failed to retrieve schema from provisioner %q: %w", addr, resp.Diagnostics.Err())
|
||||
}
|
||||
return resp.Provisioner, nil
|
||||
})
|
||||
cp.provisionerSchemas[addr] = entry
|
||||
}
|
||||
// This lock is only for access to the map. We don't need to hold the lock when calling
|
||||
// "entry" because [sync.OnceValues] handles synchronization itself.
|
||||
// We don't defer unlock as the majority of the work of this function happens in calling "entry"
|
||||
// and we want to release as soon as possible for multiple concurrent callers of different provisioners
|
||||
cp.provisionerSchemasLock.Unlock()
|
||||
|
||||
return entry()
|
||||
return cp.provisioners.ProvisionerSchema(addr)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
)
|
||||
|
|
@ -31,7 +32,7 @@ func simpleMockPluginLibrary() *contextPlugins {
|
|||
// factory into real code under test.
|
||||
provider := simpleMockProvider()
|
||||
provisioner := simpleMockProvisioner()
|
||||
ret := newContextPlugins(map[addrs.Provider]providers.Factory{
|
||||
ret := newContextPlugins(plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): func() (providers.Interface, error) {
|
||||
return provider, nil
|
||||
},
|
||||
|
|
@ -39,7 +40,7 @@ func simpleMockPluginLibrary() *contextPlugins {
|
|||
"test": func() (provisioners.Interface, error) {
|
||||
return provisioner, nil
|
||||
},
|
||||
})
|
||||
}))
|
||||
return ret
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/legacy/hcl2shim"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
)
|
||||
|
|
@ -41,9 +42,9 @@ func TestContext2Refresh(t *testing.T) {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
schema := p.GetProviderSchemaResponse.ResourceTypes["aws_instance"].Block
|
||||
|
|
@ -129,9 +130,9 @@ func TestContext2Refresh_dynamicAttr(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
schema := p.GetProviderSchemaResponse.ResourceTypes["test_instance"].Block
|
||||
|
|
@ -204,9 +205,9 @@ func TestContext2Refresh_dataComputedModuleVar(t *testing.T) {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, states.NewState(), &PlanOpts{Mode: plans.RefreshOnlyMode})
|
||||
|
|
@ -268,9 +269,9 @@ func TestContext2Refresh_targeted(t *testing.T) {
|
|||
|
||||
m := testModule(t, "refresh-targeted")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
refreshedResources := make([]string, 0, 2)
|
||||
|
|
@ -355,9 +356,9 @@ func TestContext2Refresh_excluded(t *testing.T) {
|
|||
|
||||
m := testModule(t, "refresh-targeted")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
refreshedResources := make([]string, 0, 2)
|
||||
|
|
@ -439,9 +440,9 @@ func TestContext2Refresh_targetedCount(t *testing.T) {
|
|||
|
||||
m := testModule(t, "refresh-targeted-count")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
refreshedResources := make([]string, 0, 2)
|
||||
|
|
@ -532,9 +533,9 @@ func TestContext2Refresh_excludedCount(t *testing.T) {
|
|||
|
||||
m := testModule(t, "refresh-targeted-count")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
refreshedResources := make([]string, 0, 2)
|
||||
|
|
@ -620,9 +621,9 @@ func TestContext2Refresh_targetedCountIndex(t *testing.T) {
|
|||
|
||||
m := testModule(t, "refresh-targeted-count")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
refreshedResources := make([]string, 0, 2)
|
||||
|
|
@ -707,9 +708,9 @@ func TestContext2Refresh_excludedCountIndex(t *testing.T) {
|
|||
|
||||
m := testModule(t, "refresh-targeted-count")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
refreshedResources := make([]string, 0, 2)
|
||||
|
|
@ -762,9 +763,9 @@ func TestContext2Refresh_moduleComputedVar(t *testing.T) {
|
|||
|
||||
m := testModule(t, "refresh-module-computed-var")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
// This was failing (see GH-2188) at some point, so this test just
|
||||
|
|
@ -783,9 +784,9 @@ func TestContext2Refresh_delete(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(root, "aws_instance.web", `{"id":"foo"}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
||||
|
|
@ -807,9 +808,9 @@ func TestContext2Refresh_ignoreUncreated(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "refresh-basic")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
||||
|
|
@ -838,9 +839,9 @@ func TestContext2Refresh_hook(t *testing.T) {
|
|||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Hooks: []Hook{h},
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
if _, diags := ctx.Refresh(context.Background(), m, state, &PlanOpts{Mode: plans.NormalMode}); diags.HasErrors() {
|
||||
|
|
@ -865,9 +866,9 @@ func TestContext2Refresh_modules(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(child, "aws_instance.web", `{"id":"baz"}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||
|
|
@ -923,9 +924,9 @@ func TestContext2Refresh_moduleInputComputedOutput(t *testing.T) {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
if _, diags := ctx.Refresh(context.Background(), m, states.NewState(), &PlanOpts{Mode: plans.NormalMode}); diags.HasErrors() {
|
||||
|
|
@ -937,9 +938,9 @@ func TestContext2Refresh_moduleVarModule(t *testing.T) {
|
|||
m := testModule(t, "refresh-module-var-module")
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
if _, diags := ctx.Refresh(context.Background(), m, states.NewState(), &PlanOpts{Mode: plans.NormalMode}); diags.HasErrors() {
|
||||
|
|
@ -952,9 +953,9 @@ func TestContext2Refresh_noState(t *testing.T) {
|
|||
p := testProvider("aws")
|
||||
m := testModule(t, "refresh-no-state")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
||||
|
|
@ -998,9 +999,9 @@ func TestContext2Refresh_output(t *testing.T) {
|
|||
root.SetOutputValue("foo", cty.StringVal("foo"), false, "")
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
s, diags := ctx.Refresh(context.Background(), m, state, &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1046,9 +1047,9 @@ func TestContext2Refresh_outputPartial(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(root, "aws_instance.foo", `{}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
s, diags := ctx.Refresh(context.Background(), m, state, &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1072,9 +1073,9 @@ func TestContext2Refresh_stateBasic(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(root, "aws_instance.web", `{"id":"bar"}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
schema := p.GetProviderSchemaResponse.ResourceTypes["aws_instance"].Block
|
||||
|
|
@ -1142,9 +1143,9 @@ func TestContext2Refresh_dataCount(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
s, diags := ctx.Refresh(context.Background(), m, states.NewState(), &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1177,9 +1178,9 @@ func TestContext2Refresh_dataState(t *testing.T) {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("null"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
var readStateVal cty.Value
|
||||
|
|
@ -1241,9 +1242,9 @@ func TestContext2Refresh_dataStateRefData(t *testing.T) {
|
|||
m := testModule(t, "refresh-data-ref-data")
|
||||
state := states.NewState()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("null"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ReadDataSourceFn = func(req providers.ReadDataSourceRequest) providers.ReadDataSourceResponse {
|
||||
|
|
@ -1277,9 +1278,9 @@ func TestContext2Refresh_tainted(t *testing.T) {
|
|||
testSetResourceInstanceTainted(root, "aws_instance.web", `{"id":"bar"}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||
// add the required id
|
||||
|
|
@ -1318,7 +1319,7 @@ func TestContext2Refresh_unknownProvider(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(root, "aws_instance.web", `{"id":"foo"}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
c, diags := NewContext(&ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{},
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{}, nil),
|
||||
})
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
|
|
@ -1359,9 +1360,9 @@ func TestContext2Refresh_vars(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(root, "aws_instance.web", `{"id":"foo"}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
readStateVal, err := schema.CoerceValue(cty.ObjectVal(map[string]cty.Value{
|
||||
|
|
@ -1455,9 +1456,9 @@ func TestContext2Refresh_orphanModule(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(grandchild, "aws_instance.baz", `{"id":"i-cde345"}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
testCheckDeadlock(t, func() {
|
||||
|
|
@ -1496,9 +1497,9 @@ func TestContext2Validate(t *testing.T) {
|
|||
|
||||
m := testModule(t, "validate-good")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -1516,9 +1517,9 @@ func TestContext2Refresh_updateProviderInState(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(root, "aws_instance.bar", `{"id":"foo"}`, `provider["registry.opentofu.org/hashicorp/aws"].baz`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
expected := strings.TrimSpace(`
|
||||
|
|
@ -1584,9 +1585,9 @@ func TestContext2Refresh_schemaUpgradeFlatmap(t *testing.T) {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Refresh(context.Background(), m, s, &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1667,9 +1668,9 @@ func TestContext2Refresh_schemaUpgradeJSON(t *testing.T) {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Refresh(context.Background(), m, s, &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1723,9 +1724,9 @@ data "aws_data_source" "foo" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
_, diags := ctx.Refresh(context.Background(), m, states.NewState(), &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1771,9 +1772,9 @@ func TestContext2Refresh_dataResourceDependsOn(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(root, "test_resource.a", `{"id":"a"}`, `provider["registry.opentofu.org/hashicorp/test"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
_, diags := ctx.Refresh(context.Background(), m, state, &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1816,9 +1817,9 @@ resource "aws_instance" "bar" {
|
|||
p := testProvider("aws")
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
state, diags := ctx.Refresh(context.Background(), m, state, &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1863,9 +1864,9 @@ func TestContext2Refresh_dataSourceOrphan(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
_, diags := ctx.Refresh(context.Background(), m, state, &PlanOpts{Mode: plans.NormalMode})
|
||||
|
|
@ -1949,9 +1950,9 @@ resource "test_resource" "foo" {
|
|||
)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan(context.Background(), m, state, &PlanOpts{Mode: plans.RefreshOnlyMode})
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ func (c *Context) newEngineShim(ctx context.Context, config *configs.Config, inp
|
|||
|
||||
tempLoader, _ := configload.NewLoader(&configload.Config{})
|
||||
|
||||
plugins := plugins.NewRuntimePlugins(c.plugins.providerFactories, c.plugins.provisionerFactories)
|
||||
plugins := plugins.NewRuntimePluginsTemp(c.plugins.providers, c.plugins.provisioners)
|
||||
evalCtx := &eval.EvalContext{
|
||||
RootModuleDir: config.Module.SourceDir,
|
||||
OriginalWorkingDir: c.meta.OriginalWorkingDir,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/legacy/hcl2shim"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plans/planfile"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
|
|
@ -267,7 +268,7 @@ func TestContext_contextValuesPropagation(t *testing.T) {
|
|||
|
||||
ctx, probe := tracing.NewContextProbe(t, t.Context())
|
||||
tofuCtx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewBuiltInProvider("test"): providers.FactoryFixed(&MockProvider{
|
||||
GetProviderSchemaResponse: &providers.GetProviderSchemaResponse{
|
||||
Provider: providers.Schema{
|
||||
|
|
@ -288,7 +289,7 @@ func TestContext_contextValuesPropagation(t *testing.T) {
|
|||
State: cty.EmptyObjectVal,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
m := testModuleInline(t, map[string]string{
|
||||
"main.tf": `
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
|
|
@ -34,9 +35,9 @@ func TestContext2Validate_badCount(t *testing.T) {
|
|||
|
||||
m := testModule(t, "validate-bad-count")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -57,9 +58,9 @@ func TestContext2Validate_badResource_reference(t *testing.T) {
|
|||
|
||||
m := testModule(t, "validate-bad-resource-count")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -83,9 +84,9 @@ func TestContext2Validate_badVar(t *testing.T) {
|
|||
|
||||
m := testModule(t, "validate-bad-var")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -150,10 +151,10 @@ func TestContext2Validate_computedVar(t *testing.T) {
|
|||
|
||||
m := testModule(t, "validate-computed-var")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(pt),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateProviderConfigFn = func(req providers.ValidateProviderConfigRequest) (resp providers.ValidateProviderConfigResponse) {
|
||||
|
|
@ -200,9 +201,9 @@ func TestContext2Validate_computedInFunction(t *testing.T) {
|
|||
|
||||
m := testModule(t, "validate-computed-in-function")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -238,9 +239,9 @@ func TestContext2Validate_countComputed(t *testing.T) {
|
|||
|
||||
m := testModule(t, "validate-count-computed")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -262,9 +263,9 @@ func TestContext2Validate_countNegative(t *testing.T) {
|
|||
}
|
||||
m := testModule(t, "validate-count-negative")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -288,9 +289,9 @@ func TestContext2Validate_countVariable(t *testing.T) {
|
|||
}
|
||||
m := testModule(t, "apply-count-variable")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -314,9 +315,9 @@ func TestContext2Validate_countVariableNoDefault(t *testing.T) {
|
|||
},
|
||||
}
|
||||
c, diags := NewContext(&ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
|
|
@ -342,9 +343,9 @@ func TestContext2Validate_moduleBadOutput(t *testing.T) {
|
|||
}
|
||||
m := testModule(t, "validate-bad-module-output")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -368,9 +369,9 @@ func TestContext2Validate_moduleGood(t *testing.T) {
|
|||
}
|
||||
m := testModule(t, "validate-good-module")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -393,9 +394,9 @@ func TestContext2Validate_moduleBadResource(t *testing.T) {
|
|||
}
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateResourceConfigResponse = &providers.ValidateResourceConfigResponse{
|
||||
|
|
@ -424,9 +425,9 @@ func TestContext2Validate_moduleDepsShouldNotCycle(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -458,9 +459,9 @@ func TestContext2Validate_moduleProviderVar(t *testing.T) {
|
|||
}
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateProviderConfigFn = func(req providers.ValidateProviderConfigRequest) (resp providers.ValidateProviderConfigResponse) {
|
||||
|
|
@ -499,9 +500,9 @@ func TestContext2Validate_moduleProviderInheritUnused(t *testing.T) {
|
|||
}
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateProviderConfigFn = func(req providers.ValidateProviderConfigRequest) (resp providers.ValidateProviderConfigResponse) {
|
||||
|
|
@ -535,9 +536,9 @@ func TestContext2Validate_orphans(t *testing.T) {
|
|||
m := testModule(t, "validate-good")
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateResourceConfigFn = func(req providers.ValidateResourceConfigRequest) providers.ValidateResourceConfigResponse {
|
||||
|
|
@ -577,9 +578,9 @@ func TestContext2Validate_providerConfig_bad(t *testing.T) {
|
|||
}
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateProviderConfigResponse = &providers.ValidateProviderConfigResponse{
|
||||
|
|
@ -616,9 +617,9 @@ func TestContext2Validate_providerConfig_skippedEmpty(t *testing.T) {
|
|||
}
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateProviderConfigResponse = &providers.ValidateProviderConfigResponse{
|
||||
|
|
@ -652,9 +653,9 @@ func TestContext2Validate_providerConfig_good(t *testing.T) {
|
|||
}
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -687,9 +688,9 @@ func TestContext2Validate_requiredProviderConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -716,12 +717,11 @@ func TestContext2Validate_provisionerConfig_bad(t *testing.T) {
|
|||
pr := simpleMockProvisioner()
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
Provisioners: map[string]provisioners.Factory{
|
||||
}, map[string]provisioners.Factory{
|
||||
"shell": testProvisionerFuncFixed(pr),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
p.ValidateProviderConfigResponse = &providers.ValidateProviderConfigResponse{
|
||||
|
|
@ -752,12 +752,11 @@ func TestContext2Validate_badResourceConnection(t *testing.T) {
|
|||
pr := simpleMockProvisioner()
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
Provisioners: map[string]provisioners.Factory{
|
||||
}, map[string]provisioners.Factory{
|
||||
"shell": testProvisionerFuncFixed(pr),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -785,12 +784,11 @@ func TestContext2Validate_badProvisionerConnection(t *testing.T) {
|
|||
pr := simpleMockProvisioner()
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
Provisioners: map[string]provisioners.Factory{
|
||||
}, map[string]provisioners.Factory{
|
||||
"shell": testProvisionerFuncFixed(pr),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -834,12 +832,11 @@ func TestContext2Validate_provisionerConfig_good(t *testing.T) {
|
|||
}
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
Provisioners: map[string]provisioners.Factory{
|
||||
}, map[string]provisioners.Factory{
|
||||
"shell": testProvisionerFuncFixed(pr),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -863,9 +860,9 @@ func TestContext2Validate_requiredVar(t *testing.T) {
|
|||
},
|
||||
}
|
||||
c, diags := NewContext(&ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
assertNoDiagnostics(t, diags)
|
||||
|
||||
|
|
@ -899,9 +896,9 @@ func TestContext2Validate_resourceConfig_bad(t *testing.T) {
|
|||
},
|
||||
}
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateResourceConfigResponse = &providers.ValidateResourceConfigResponse{
|
||||
|
|
@ -929,9 +926,9 @@ func TestContext2Validate_resourceConfig_good(t *testing.T) {
|
|||
},
|
||||
}
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := c.Validate(context.Background(), m)
|
||||
|
|
@ -957,9 +954,9 @@ func TestContext2Validate_tainted(t *testing.T) {
|
|||
|
||||
m := testModule(t, "validate-good")
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
p.ValidateResourceConfigFn = func(req providers.ValidateResourceConfigRequest) providers.ValidateResourceConfigResponse {
|
||||
|
|
@ -1001,12 +998,11 @@ func TestContext2Validate_targetedDestroy(t *testing.T) {
|
|||
testSetResourceInstanceCurrent(root, "aws_instance.bar", `{"id":"i-abc123"}`, `provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
Provisioners: map[string]provisioners.Factory{
|
||||
}, map[string]provisioners.Factory{
|
||||
"shell": testProvisionerFuncFixed(pr),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1030,9 +1026,9 @@ func TestContext2Validate_varRefUnknown(t *testing.T) {
|
|||
},
|
||||
}
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
var value cty.Value
|
||||
|
|
@ -1071,9 +1067,9 @@ func TestContext2Validate_interpolateVar(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("template"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: input,
|
||||
})
|
||||
|
||||
|
|
@ -1103,9 +1099,9 @@ func TestContext2Validate_interpolateComputedModuleVarDef(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: input,
|
||||
})
|
||||
|
||||
|
|
@ -1123,9 +1119,9 @@ func TestContext2Validate_interpolateMap(t *testing.T) {
|
|||
p := testProvider("template")
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("template"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
UIInput: input,
|
||||
})
|
||||
|
||||
|
|
@ -1174,9 +1170,9 @@ resource "aws_instance" "foo" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1205,9 +1201,9 @@ output "out" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1241,9 +1237,9 @@ resource "aws_instance" "foo" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1299,9 +1295,9 @@ output "out" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1329,9 +1325,9 @@ output "out" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1359,9 +1355,9 @@ output "out" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1388,9 +1384,9 @@ resource "test_instance" "bar" {
|
|||
|
||||
p := testProvider("test")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1420,9 +1416,9 @@ resource "test_instance" "bar" {
|
|||
|
||||
p := testProvider("test")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1444,9 +1440,9 @@ func TestContext2Validate_variableCustomValidationsFail(t *testing.T) {
|
|||
|
||||
p := testProvider("test")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1478,9 +1474,9 @@ variable "test" {
|
|||
|
||||
p := testProvider("test")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1539,9 +1535,9 @@ resource "aws_instance" "foo" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1566,9 +1562,9 @@ resource "aws_instance" "foo" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1596,9 +1592,9 @@ resource "aws_instance" "foo" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1677,9 +1673,9 @@ output "out" {
|
|||
|
||||
p := testProvider("aws")
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -1791,9 +1787,9 @@ resource "test_instance" "a" {
|
|||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
if diags.HasErrors() {
|
||||
|
|
@ -1830,12 +1826,11 @@ func TestContext2Validate_sensitiveProvisionerConfig(t *testing.T) {
|
|||
pr := simpleMockProvisioner()
|
||||
|
||||
c := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
Provisioners: map[string]provisioners.Factory{
|
||||
}, map[string]provisioners.Factory{
|
||||
"test": testProvisionerFuncFixed(pr),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
pr.ValidateProvisionerConfigFn = func(r provisioners.ValidateProvisionerConfigRequest) provisioners.ValidateProvisionerConfigResponse {
|
||||
|
|
@ -1934,9 +1929,9 @@ resource "test_instance" "c" {
|
|||
`})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2001,9 +1996,9 @@ resource "test_object" "t" {
|
|||
|
||||
p := simpleMockProvider()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2058,9 +2053,9 @@ output "out" {
|
|||
`})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2134,9 +2129,9 @@ resource "aws_instance" "test" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2177,9 +2172,9 @@ resource "aws_instance" "test" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2223,9 +2218,9 @@ resource "aws_instance" "test" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2264,9 +2259,9 @@ resource "aws_instance" "test" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2313,9 +2308,9 @@ resource "aws_instance" "test" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2354,9 +2349,9 @@ resource "aws_instance" "test" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2400,9 +2395,9 @@ resource "aws_instance" "test" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2443,9 +2438,9 @@ resource "aws_instance" "test" {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2477,9 +2472,9 @@ locals {
|
|||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2496,9 +2491,9 @@ func TestContext2Validate_rangeOverZeroPlanTimestamp(t *testing.T) {
|
|||
m := testModule(t, "plan_range_over_plan_timestamp")
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2530,9 +2525,9 @@ resource "test_object" "t" {
|
|||
|
||||
p := simpleMockProvider()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2561,9 +2556,9 @@ resource "test_object" "t" {
|
|||
|
||||
p := simpleMockProvider()
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
diags := ctx.Validate(context.Background(), m)
|
||||
|
|
@ -2605,9 +2600,9 @@ func TestContext2Validate_importWithForEachOnUnknown(t *testing.T) {
|
|||
hook := new(MockHook)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Hooks: []Hook{hook},
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
p.ReadResourceFn = func(request providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||
return providers.ReadResourceResponse{
|
||||
|
|
@ -2709,9 +2704,9 @@ func TestContext2Validate_importIntoModuleResource(t *testing.T) {
|
|||
hook := new(MockHook)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Hooks: []Hook{hook},
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
p.ReadResourceFn = func(request providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||
return providers.ReadResourceResponse{
|
||||
|
|
@ -2763,9 +2758,9 @@ func TestContext2Validate_importIntoUnexistingResourceBlock(t *testing.T) {
|
|||
hook := new(MockHook)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Hooks: []Hook{hook},
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
p.ReadResourceFn = func(request providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||
return providers.ReadResourceResponse{
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/instances"
|
||||
"github.com/opentofu/opentofu/internal/lang"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/refactoring"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -41,20 +40,12 @@ type EvalContext interface {
|
|||
// Input is the UIInput object for interacting with the UI.
|
||||
Input() UIInput
|
||||
|
||||
// InitProvider initializes the provider with the given address, and returns
|
||||
// the implementation of the resource provider or an error.
|
||||
//
|
||||
// It is an error to initialize the same provider more than once. This
|
||||
// method will panic if the module instance address of the given provider
|
||||
// configuration does not match the Path() of the EvalContext.
|
||||
InitProvider(ctx context.Context, addr addrs.AbsProviderConfig, key addrs.InstanceKey) (providers.Interface, error)
|
||||
|
||||
// ProviderSchema retrieves the schema for a particular provider, which
|
||||
// must have already been initialized with InitProvider.
|
||||
//
|
||||
// This method expects an _absolute_ provider configuration address, since
|
||||
// resources in one module are able to use providers from other modules.
|
||||
ProviderSchema(context.Context, addrs.AbsProviderConfig) (providers.ProviderSchema, error)
|
||||
// Providers is the [plugins.ProviderManager] for interacting
|
||||
// with providers in the current operation.
|
||||
Providers() plugins.ProviderManager
|
||||
// Provisioners is the [plugins.ProvisionerManager] for interacting
|
||||
// with provisioners in the current operation.
|
||||
Provisioners() plugins.ProvisionerManager
|
||||
|
||||
// ProviderInput and SetProviderInput are used to configure providers
|
||||
// from user input.
|
||||
|
|
@ -64,17 +55,6 @@ type EvalContext interface {
|
|||
ProviderInput(context.Context, addrs.AbsProviderConfig) map[string]cty.Value
|
||||
SetProviderInput(context.Context, addrs.AbsProviderConfig, map[string]cty.Value)
|
||||
|
||||
// Provisioner gets the provisioner instance with the given name.
|
||||
Provisioner(string) (provisioners.Interface, error)
|
||||
|
||||
// ProvisionerSchema retrieves the main configuration schema for a
|
||||
// particular provisioner, which must have already been initialized with
|
||||
// InitProvisioner.
|
||||
ProvisionerSchema(string) (*configschema.Block, error)
|
||||
|
||||
// CloseProvisioner closes all provisioner plugins.
|
||||
CloseProvisioners() error
|
||||
|
||||
// EvaluateBlock takes the given raw configuration block and associated
|
||||
// schema and evaluates it to produce a value of an object type that
|
||||
// conforms to the implied type of the schema.
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/instances"
|
||||
"github.com/opentofu/opentofu/internal/lang"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/refactoring"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -65,12 +64,8 @@ type BuiltinEvalContext struct {
|
|||
Hooks []Hook
|
||||
InputValue UIInput
|
||||
|
||||
ProviderLock *sync.Mutex
|
||||
ProviderCache map[string]map[addrs.InstanceKey]providers.Interface
|
||||
ProviderInputConfig map[string]map[string]cty.Value
|
||||
|
||||
ProvisionerLock *sync.Mutex
|
||||
ProvisionerCache map[string]provisioners.Interface
|
||||
ProviderInputConfigLock *sync.Mutex
|
||||
ProviderInputConfig map[string]map[string]cty.Value
|
||||
|
||||
ChangesValue *plans.ChangesSync
|
||||
StateValue *states.SyncState
|
||||
|
|
@ -127,39 +122,9 @@ func (c *BuiltinEvalContext) Input() UIInput {
|
|||
return c.InputValue
|
||||
}
|
||||
|
||||
func (c *BuiltinEvalContext) InitProvider(ctx context.Context, addr addrs.AbsProviderConfig, providerInstanceKey addrs.InstanceKey) (providers.Interface, error) {
|
||||
c.ProviderLock.Lock()
|
||||
defer c.ProviderLock.Unlock()
|
||||
|
||||
providerAddrKey := addr.String()
|
||||
|
||||
if c.ProviderCache[providerAddrKey] == nil {
|
||||
c.ProviderCache[providerAddrKey] = make(map[addrs.InstanceKey]providers.Interface)
|
||||
}
|
||||
|
||||
// If we have already initialized, it is an error
|
||||
if _, ok := c.ProviderCache[providerAddrKey][providerInstanceKey]; ok {
|
||||
return nil, fmt.Errorf("%s is already initialized", addr)
|
||||
}
|
||||
|
||||
p, err := c.Plugins.NewProviderInstance(addr.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Printf("[TRACE] BuiltinEvalContext: Initialized %q%s provider for %s", addr.String(), providerInstanceKey, addr)
|
||||
c.ProviderCache[providerAddrKey][providerInstanceKey] = p
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (c *BuiltinEvalContext) ProviderSchema(ctx context.Context, addr addrs.AbsProviderConfig) (providers.ProviderSchema, error) {
|
||||
return c.Plugins.ProviderSchema(ctx, addr.Provider)
|
||||
}
|
||||
|
||||
func (c *BuiltinEvalContext) ProviderInput(_ context.Context, pc addrs.AbsProviderConfig) map[string]cty.Value {
|
||||
c.ProviderLock.Lock()
|
||||
defer c.ProviderLock.Unlock()
|
||||
c.ProviderInputConfigLock.Lock()
|
||||
defer c.ProviderInputConfigLock.Unlock()
|
||||
|
||||
if !c.Path().IsForModule(pc.Module) {
|
||||
// This indicates incorrect use of InitProvider: it should be used
|
||||
|
|
@ -184,46 +149,17 @@ func (c *BuiltinEvalContext) SetProviderInput(_ context.Context, pc addrs.AbsPro
|
|||
}
|
||||
|
||||
// Save the configuration
|
||||
c.ProviderLock.Lock()
|
||||
c.ProviderInputConfigLock.Lock()
|
||||
c.ProviderInputConfig[absProvider.String()] = vals
|
||||
c.ProviderLock.Unlock()
|
||||
c.ProviderInputConfigLock.Unlock()
|
||||
}
|
||||
|
||||
func (c *BuiltinEvalContext) Provisioner(n string) (provisioners.Interface, error) {
|
||||
c.ProvisionerLock.Lock()
|
||||
defer c.ProvisionerLock.Unlock()
|
||||
|
||||
p, ok := c.ProvisionerCache[n]
|
||||
if !ok {
|
||||
var err error
|
||||
p, err = c.Plugins.NewProvisionerInstance(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.ProvisionerCache[n] = p
|
||||
}
|
||||
|
||||
return p, nil
|
||||
func (c *BuiltinEvalContext) Providers() plugins.ProviderManager {
|
||||
return c.Plugins.providers
|
||||
}
|
||||
|
||||
func (c *BuiltinEvalContext) ProvisionerSchema(n string) (*configschema.Block, error) {
|
||||
return c.Plugins.ProvisionerSchema(n)
|
||||
}
|
||||
|
||||
func (c *BuiltinEvalContext) CloseProvisioners() error {
|
||||
var diags tfdiags.Diagnostics
|
||||
c.ProvisionerLock.Lock()
|
||||
defer c.ProvisionerLock.Unlock()
|
||||
|
||||
for name, prov := range c.ProvisionerCache {
|
||||
err := prov.Close()
|
||||
if err != nil {
|
||||
diags = diags.Append(fmt.Errorf("provisioner.Close %s: %w", name, err))
|
||||
}
|
||||
}
|
||||
|
||||
return diags.Err()
|
||||
func (c *BuiltinEvalContext) Provisioners() plugins.ProvisionerManager {
|
||||
return c.Plugins.provisioners
|
||||
}
|
||||
|
||||
func (c *BuiltinEvalContext) EvaluateBlock(ctx context.Context, body hcl.Body, schema *configschema.Block, self addrs.Referenceable, keyData InstanceKeyEvalData) (cty.Value, hcl.Body, tfdiags.Diagnostics) {
|
||||
|
|
@ -319,9 +255,9 @@ func (c *BuiltinEvalContext) EvaluateReplaceTriggeredBy(ctx context.Context, exp
|
|||
// Since we have a traversal after the resource reference, we will need to
|
||||
// decode the changes, which means we need a schema.
|
||||
providerAddr := change.ProviderAddr
|
||||
schema, err := c.ProviderSchema(ctx, providerAddr)
|
||||
if err != nil {
|
||||
diags = diags.Append(err)
|
||||
schema, schemaDiags := c.Providers().GetProviderSchema(ctx, providerAddr.Provider)
|
||||
if schemaDiags.HasErrors() {
|
||||
diags = diags.Append(schemaDiags)
|
||||
return nil, false, diags
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
|
|
@ -22,12 +21,12 @@ func TestBuiltinEvalContextProviderInput(t *testing.T) {
|
|||
ctx1 := testBuiltinEvalContext(t)
|
||||
ctx1 = ctx1.WithPath(addrs.RootModuleInstance).(*BuiltinEvalContext)
|
||||
ctx1.ProviderInputConfig = cache
|
||||
ctx1.ProviderLock = &lock
|
||||
ctx1.ProviderInputConfigLock = &lock
|
||||
|
||||
ctx2 := testBuiltinEvalContext(t)
|
||||
ctx2 = ctx2.WithPath(addrs.RootModuleInstance.Child("child", addrs.NoKey)).(*BuiltinEvalContext)
|
||||
ctx2.ProviderInputConfig = cache
|
||||
ctx2.ProviderLock = &lock
|
||||
ctx2.ProviderInputConfigLock = &lock
|
||||
|
||||
providerAddr1 := addrs.AbsProviderConfig{
|
||||
Module: addrs.RootModule,
|
||||
|
|
@ -55,39 +54,6 @@ func TestBuiltinEvalContextProviderInput(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuildingEvalContextInitProvider(t *testing.T) {
|
||||
var lock sync.Mutex
|
||||
|
||||
testP := &MockProvider{}
|
||||
|
||||
ctx := testBuiltinEvalContext(t)
|
||||
ctx = ctx.WithPath(addrs.RootModuleInstance).(*BuiltinEvalContext)
|
||||
ctx.ProviderLock = &lock
|
||||
ctx.ProviderCache = make(map[string]map[addrs.InstanceKey]providers.Interface)
|
||||
ctx.Plugins = newContextPlugins(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): providers.FactoryFixed(testP),
|
||||
}, nil)
|
||||
|
||||
providerAddrDefault := addrs.AbsProviderConfig{
|
||||
Module: addrs.RootModule,
|
||||
Provider: addrs.NewDefaultProvider("test"),
|
||||
}
|
||||
providerAddrAlias := addrs.AbsProviderConfig{
|
||||
Module: addrs.RootModule,
|
||||
Provider: addrs.NewDefaultProvider("test"),
|
||||
Alias: "foo",
|
||||
}
|
||||
|
||||
_, err := ctx.InitProvider(t.Context(), providerAddrDefault, addrs.NoKey)
|
||||
if err != nil {
|
||||
t.Fatalf("error initializing provider test: %s", err)
|
||||
}
|
||||
_, err = ctx.InitProvider(t.Context(), providerAddrAlias, addrs.NoKey)
|
||||
if err != nil {
|
||||
t.Fatalf("error initializing provider test.foo: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testBuiltinEvalContext(t *testing.T) *BuiltinEvalContext {
|
||||
return &BuiltinEvalContext{}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/instances"
|
||||
"github.com/opentofu/opentofu/internal/lang"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/refactoring"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -40,16 +40,8 @@ type MockEvalContext struct {
|
|||
InputCalled bool
|
||||
InputInput UIInput
|
||||
|
||||
InitProviderCalled bool
|
||||
InitProviderType string
|
||||
InitProviderAddr addrs.AbsProviderConfig
|
||||
InitProviderProvider providers.Interface
|
||||
InitProviderError error
|
||||
|
||||
ProviderSchemaCalled bool
|
||||
ProviderSchemaAddr addrs.AbsProviderConfig
|
||||
ProviderSchemaSchema providers.ProviderSchema
|
||||
ProviderSchemaError error
|
||||
ProvidersCalled bool
|
||||
ProvidersProviders plugins.ProviderManager
|
||||
|
||||
ProviderInputCalled bool
|
||||
ProviderInputAddr addrs.AbsProviderConfig
|
||||
|
|
@ -59,16 +51,8 @@ type MockEvalContext struct {
|
|||
SetProviderInputAddr addrs.AbsProviderConfig
|
||||
SetProviderInputValues map[string]cty.Value
|
||||
|
||||
ProvisionerCalled bool
|
||||
ProvisionerName string
|
||||
ProvisionerProvisioner provisioners.Interface
|
||||
|
||||
ProvisionerSchemaCalled bool
|
||||
ProvisionerSchemaName string
|
||||
ProvisionerSchemaSchema *configschema.Block
|
||||
ProvisionerSchemaError error
|
||||
|
||||
CloseProvisionersCalled bool
|
||||
ProvisionersCalled bool
|
||||
ProvisionersProvisioners plugins.ProvisionerManager
|
||||
|
||||
EvaluateBlockCalled bool
|
||||
EvaluateBlockBody hcl.Body
|
||||
|
|
@ -170,17 +154,15 @@ func (c *MockEvalContext) Input() UIInput {
|
|||
return c.InputInput
|
||||
}
|
||||
|
||||
func (c *MockEvalContext) InitProvider(_ context.Context, addr addrs.AbsProviderConfig, _ addrs.InstanceKey) (providers.Interface, error) {
|
||||
c.InitProviderCalled = true
|
||||
c.InitProviderType = addr.String()
|
||||
c.InitProviderAddr = addr
|
||||
return c.InitProviderProvider, c.InitProviderError
|
||||
func (c *MockEvalContext) installProvider(addr addrs.Provider, p providers.Interface) {
|
||||
c.ProvidersProviders = plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addr: func() (providers.Interface, error) { return p, nil },
|
||||
}, nil).NewProviderManager()
|
||||
}
|
||||
|
||||
func (c *MockEvalContext) ProviderSchema(_ context.Context, addr addrs.AbsProviderConfig) (providers.ProviderSchema, error) {
|
||||
c.ProviderSchemaCalled = true
|
||||
c.ProviderSchemaAddr = addr
|
||||
return c.ProviderSchemaSchema, c.ProviderSchemaError
|
||||
func (c *MockEvalContext) Providers() plugins.ProviderManager {
|
||||
c.ProvidersCalled = true
|
||||
return c.ProvidersProviders
|
||||
}
|
||||
|
||||
func (c *MockEvalContext) ProviderInput(_ context.Context, addr addrs.AbsProviderConfig) map[string]cty.Value {
|
||||
|
|
@ -195,21 +177,9 @@ func (c *MockEvalContext) SetProviderInput(_ context.Context, addr addrs.AbsProv
|
|||
c.SetProviderInputValues = vals
|
||||
}
|
||||
|
||||
func (c *MockEvalContext) Provisioner(n string) (provisioners.Interface, error) {
|
||||
c.ProvisionerCalled = true
|
||||
c.ProvisionerName = n
|
||||
return c.ProvisionerProvisioner, nil
|
||||
}
|
||||
|
||||
func (c *MockEvalContext) ProvisionerSchema(n string) (*configschema.Block, error) {
|
||||
c.ProvisionerSchemaCalled = true
|
||||
c.ProvisionerSchemaName = n
|
||||
return c.ProvisionerSchemaSchema, c.ProvisionerSchemaError
|
||||
}
|
||||
|
||||
func (c *MockEvalContext) CloseProvisioners() error {
|
||||
c.CloseProvisionersCalled = true
|
||||
return nil
|
||||
func (c *MockEvalContext) Provisioners() plugins.ProvisionerManager {
|
||||
c.ProvisionersCalled = true
|
||||
return c.ProvisionersProvisioners
|
||||
}
|
||||
|
||||
func (c *MockEvalContext) EvaluateBlock(_ context.Context, body hcl.Body, schema *configschema.Block, self addrs.Referenceable, keyData InstanceKeyEvalData) (cty.Value, hcl.Body, tfdiags.Diagnostics) {
|
||||
|
|
|
|||
|
|
@ -1015,8 +1015,8 @@ func (d *evaluationStateData) GetResource(ctx context.Context, addr addrs.Resour
|
|||
|
||||
func (d *evaluationStateData) getResourceSchema(ctx context.Context, addr addrs.Resource, providerAddr addrs.Provider) *configschema.Block {
|
||||
// TODO: Plumb a useful context.Context through to here.
|
||||
schema, _, err := d.Evaluator.Plugins.ResourceTypeSchema(ctx, providerAddr, addr.Mode, addr.Type)
|
||||
if err != nil {
|
||||
schema, _, diags := d.Evaluator.Plugins.ResourceTypeSchema(ctx, providerAddr, addr.Mode, addr.Type)
|
||||
if diags.HasErrors() {
|
||||
// We have plenty of other codepaths that will detect and report
|
||||
// schema lookup errors before we'd reach this point, so we'll just
|
||||
// treat a failure here the same as having no schema.
|
||||
|
|
|
|||
|
|
@ -234,15 +234,16 @@ func (d *evaluationStateData) staticValidateResourceReference(ctx context.Contex
|
|||
|
||||
// TODO: Plugin a suitable context.Context through to here.
|
||||
providerFqn := modCfg.Module.ProviderForLocalConfig(cfg.ProviderConfigAddr())
|
||||
schema, _, err := d.Evaluator.Plugins.ResourceTypeSchema(ctx, providerFqn, addr.Mode, addr.Type)
|
||||
if err != nil {
|
||||
schema, _, moreDiags := d.Evaluator.Plugins.ResourceTypeSchema(ctx, providerFqn, addr.Mode, addr.Type)
|
||||
diags = diags.Append(moreDiags)
|
||||
if moreDiags.HasErrors() {
|
||||
// Prior validation should've taken care of a schema lookup error,
|
||||
// so we should never get here but we'll handle it here anyway for
|
||||
// robustness.
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: `Failed provider schema lookup`,
|
||||
Detail: fmt.Sprintf(`Couldn't load schema for %s resource type %q in %s: %s.`, modeAdjective, addr.Type, providerFqn.String(), err),
|
||||
Detail: fmt.Sprintf(`Couldn't load schema for %s resource type %q in %s: %s.`, modeAdjective, addr.Type, providerFqn.String(), diags.Err()),
|
||||
Subject: rng.ToHCL().Ptr(),
|
||||
})
|
||||
}
|
||||
|
|
@ -278,7 +279,7 @@ func (d *evaluationStateData) staticValidateResourceReference(ctx context.Contex
|
|||
|
||||
// If we got this far then we'll try to validate the remaining traversal
|
||||
// steps against our schema.
|
||||
moreDiags := schema.StaticValidateTraversal(remain)
|
||||
moreDiags = schema.StaticValidateTraversal(remain)
|
||||
diags = diags.Append(moreDiags)
|
||||
|
||||
return diags
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
)
|
||||
|
|
@ -780,9 +781,9 @@ func TestApplyGraphBuilder_withChecks(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
plugins := newContextPlugins(map[addrs.Provider]providers.Factory{
|
||||
plugins := newContextPlugins(plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): providers.FactoryFixed(awsProvider),
|
||||
}, nil)
|
||||
}, nil))
|
||||
|
||||
b := &ApplyGraphBuilder{
|
||||
Config: testModule(t, "apply-with-checks"),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/opentofu/opentofu/internal/configs"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
|
|
@ -35,10 +36,10 @@ func TestPlanGraphBuilder(t *testing.T) {
|
|||
},
|
||||
}
|
||||
openstackProvider := mockProviderWithResourceTypeSchema("openstack_floating_ip", simpleTestSchema())
|
||||
plugins := newContextPlugins(map[addrs.Provider]providers.Factory{
|
||||
plugins := newContextPlugins(plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): providers.FactoryFixed(awsProvider),
|
||||
addrs.NewDefaultProvider("openstack"): providers.FactoryFixed(openstackProvider),
|
||||
}, nil)
|
||||
}, nil))
|
||||
|
||||
b := &PlanGraphBuilder{
|
||||
Config: testModule(t, "graph-builder-plan-basic"),
|
||||
|
|
@ -79,9 +80,9 @@ func TestPlanGraphBuilder_dynamicBlock(t *testing.T) {
|
|||
},
|
||||
},
|
||||
})
|
||||
plugins := newContextPlugins(map[addrs.Provider]providers.Factory{
|
||||
plugins := newContextPlugins(plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): providers.FactoryFixed(provider),
|
||||
}, nil)
|
||||
}, nil))
|
||||
|
||||
b := &PlanGraphBuilder{
|
||||
Config: testModule(t, "graph-builder-plan-dynblock"),
|
||||
|
|
@ -135,9 +136,9 @@ func TestPlanGraphBuilder_attrAsBlocks(t *testing.T) {
|
|||
},
|
||||
},
|
||||
})
|
||||
plugins := newContextPlugins(map[addrs.Provider]providers.Factory{
|
||||
plugins := newContextPlugins(plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): providers.FactoryFixed(provider),
|
||||
}, nil)
|
||||
}, nil))
|
||||
|
||||
b := &PlanGraphBuilder{
|
||||
Config: testModule(t, "graph-builder-plan-attr-as-blocks"),
|
||||
|
|
@ -221,9 +222,9 @@ func TestPlanGraphBuilder_excludeModule(t *testing.T) {
|
|||
func TestPlanGraphBuilder_forEach(t *testing.T) {
|
||||
awsProvider := mockProviderWithResourceTypeSchema("aws_instance", simpleTestSchema())
|
||||
|
||||
plugins := newContextPlugins(map[addrs.Provider]providers.Factory{
|
||||
plugins := newContextPlugins(plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): providers.FactoryFixed(awsProvider),
|
||||
}, nil)
|
||||
}, nil))
|
||||
|
||||
b := &PlanGraphBuilder{
|
||||
Config: testModule(t, "plan-for-each"),
|
||||
|
|
@ -256,9 +257,9 @@ func TestPlanGraphBuilder_ephemeralResourceDestroy(t *testing.T) {
|
|||
b := &PlanGraphBuilder{
|
||||
Config: &configs.Config{Module: &configs.Module{}},
|
||||
Operation: walkPlanDestroy,
|
||||
Plugins: newContextPlugins(map[addrs.Provider]providers.Factory{
|
||||
Plugins: newContextPlugins(plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): providers.FactoryFixed(awsProvider),
|
||||
}, nil),
|
||||
}, nil)),
|
||||
State: &states.State{
|
||||
Modules: map[string]*states.Module{
|
||||
"": {
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/encryption"
|
||||
"github.com/opentofu/opentofu/internal/instances"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/refactoring"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -59,11 +57,7 @@ type ContextGraphWalker struct {
|
|||
variableValuesLock sync.Mutex
|
||||
variableValues map[string]map[string]cty.Value
|
||||
|
||||
providerLock sync.Mutex
|
||||
providerCache map[string]map[addrs.InstanceKey]providers.Interface
|
||||
|
||||
provisionerLock sync.Mutex
|
||||
provisionerCache map[string]provisioners.Interface
|
||||
providerInputConfigLock sync.Mutex
|
||||
}
|
||||
|
||||
var _ GraphWalker = (*ContextGraphWalker)(nil)
|
||||
|
|
@ -110,11 +104,8 @@ func (w *ContextGraphWalker) EvalContext() EvalContext {
|
|||
Plugins: w.Context.plugins,
|
||||
MoveResultsValue: w.MoveResults,
|
||||
ImportResolverValue: w.ImportResolver,
|
||||
ProviderCache: w.providerCache,
|
||||
ProviderInputConfigLock: &w.providerInputConfigLock,
|
||||
ProviderInputConfig: w.Context.providerInputConfig,
|
||||
ProviderLock: &w.providerLock,
|
||||
ProvisionerCache: w.provisionerCache,
|
||||
ProvisionerLock: &w.provisionerLock,
|
||||
ChangesValue: w.Changes,
|
||||
ChecksValue: w.Checks,
|
||||
StateValue: w.State,
|
||||
|
|
@ -132,8 +123,6 @@ func (w *ContextGraphWalker) EvalContext() EvalContext {
|
|||
|
||||
func (w *ContextGraphWalker) init() {
|
||||
w.contexts = make(map[string]*BuiltinEvalContext)
|
||||
w.providerCache = make(map[string]map[addrs.InstanceKey]providers.Interface)
|
||||
w.provisionerCache = make(map[string]provisioners.Interface)
|
||||
w.variableValues = make(map[string]map[string]cty.Value)
|
||||
|
||||
// Populate root module variable values. Other modules will be populated
|
||||
|
|
|
|||
|
|
@ -224,7 +224,11 @@ func (n *nodeCloseModule) Execute(_ context.Context, evalCtx EvalContext, op wal
|
|||
|
||||
// If this is the root module, we are cleaning up the walk, so close
|
||||
// any running provisioners
|
||||
diags = diags.Append(evalCtx.CloseProvisioners())
|
||||
provisioners := evalCtx.Provisioners()
|
||||
// Sometimes nil in tests
|
||||
if provisioners != nil {
|
||||
diags = diags.Append(provisioners.CloseAll())
|
||||
}
|
||||
|
||||
switch op {
|
||||
case walkApply, walkDestroy:
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/configs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -215,9 +216,9 @@ func TestNodeModuleVariableConstraints(t *testing.T) {
|
|||
}
|
||||
|
||||
ctxOpts := &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
}
|
||||
|
||||
t.Run("pass", func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -12,15 +12,14 @@ import (
|
|||
"log"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/instances"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
"github.com/opentofu/opentofu/internal/tracing"
|
||||
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||
"github.com/opentofu/opentofu/version"
|
||||
)
|
||||
|
||||
// traceAttrProviderAddress is a standardized trace span attribute name that we
|
||||
|
|
@ -89,81 +88,43 @@ func (n *NodeApplyableProvider) Close(ctx context.Context) error {
|
|||
|
||||
// GraphNodeExecutable
|
||||
func (n *NodeApplyableProvider) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) tfdiags.Diagnostics {
|
||||
instances, diags := n.initInstances(ctx, evalCtx, op)
|
||||
if diags.HasErrors() {
|
||||
return diags
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
n.instances = map[addrs.InstanceKey]providers.Configured{}
|
||||
|
||||
var instanceData map[addrs.InstanceKey]instances.RepetitionData
|
||||
if n.Config == nil || n.Config.Instances == nil {
|
||||
// Stub out uninstanced
|
||||
instanceData = map[addrs.InstanceKey]instances.RepetitionData{addrs.NoKey: EvalDataForNoInstanceKey}
|
||||
} else {
|
||||
instanceData = n.Config.Instances
|
||||
}
|
||||
|
||||
for key, provider := range instances {
|
||||
diags = diags.Append(n.executeInstance(ctx, evalCtx, op, key, provider))
|
||||
if op == walkValidate {
|
||||
log.Printf("[TRACE] NodeApplyableProvider: validating configuration for %s", n.Addr)
|
||||
instance, newDiags := evalCtx.Providers().NewProvider(ctx, n.Addr.Provider)
|
||||
n.instances[addrs.NoKey] = instance
|
||||
for key, data := range instanceData {
|
||||
diags = diags.Append(n.ValidateProvider(ctx, evalCtx, instance, key, data))
|
||||
}
|
||||
return diags.Append(newDiags)
|
||||
}
|
||||
|
||||
verifyConfigIsKnown := op == walkImport
|
||||
if verifyConfigIsKnown {
|
||||
log.Printf("[TRACE] NodeApplyableProvider: configuring %s (requiring that configuration is wholly known)", n.Addr)
|
||||
} else {
|
||||
log.Printf("[TRACE] NodeApplyableProvider: configuring %s", n.Addr)
|
||||
}
|
||||
|
||||
for key, data := range instanceData {
|
||||
diags = diags.Append(n.ConfigureProvider(ctx, evalCtx, key, data, verifyConfigIsKnown))
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
func (n *NodeApplyableProvider) initInstances(ctx context.Context, evalCtx EvalContext, op walkOperation) (map[addrs.InstanceKey]providers.Interface, tfdiags.Diagnostics) {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
var initKeys []addrs.InstanceKey
|
||||
// config -> init (different due to validate skipping most for_each logic)
|
||||
instanceKeys := make(map[addrs.InstanceKey]addrs.InstanceKey)
|
||||
if n.Config == nil || n.Config.Instances == nil {
|
||||
initKeys = append(initKeys, addrs.NoKey)
|
||||
instanceKeys[addrs.NoKey] = addrs.NoKey
|
||||
} else if op == walkValidate {
|
||||
// Instances are set AND we are validating
|
||||
initKeys = append(initKeys, addrs.NoKey)
|
||||
for key := range n.Config.Instances {
|
||||
instanceKeys[key] = addrs.NoKey
|
||||
}
|
||||
} else {
|
||||
// Instances are set AND we are not validating
|
||||
for key := range n.Config.Instances {
|
||||
initKeys = append(initKeys, key)
|
||||
instanceKeys[key] = key
|
||||
}
|
||||
}
|
||||
|
||||
if n.instances == nil {
|
||||
n.instances = map[addrs.InstanceKey]providers.Configured{}
|
||||
}
|
||||
|
||||
for _, key := range initKeys {
|
||||
instance, err := evalCtx.InitProvider(ctx, n.Addr, key)
|
||||
diags = diags.Append(err)
|
||||
if err == nil {
|
||||
n.instances[key] = instance
|
||||
}
|
||||
}
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
instances := make(map[addrs.InstanceKey]providers.Interface)
|
||||
for configKey, initKey := range instanceKeys {
|
||||
instances[configKey] = n.instances[initKey]
|
||||
}
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
return instances, diags
|
||||
}
|
||||
func (n *NodeApplyableProvider) executeInstance(ctx context.Context, evalCtx EvalContext, op walkOperation, providerKey addrs.InstanceKey, provider providers.Interface) tfdiags.Diagnostics {
|
||||
switch op {
|
||||
case walkValidate:
|
||||
log.Printf("[TRACE] NodeApplyableProvider: validating configuration for %s", n.Addr)
|
||||
return n.ValidateProvider(ctx, evalCtx, providerKey, provider)
|
||||
case walkPlan, walkPlanDestroy, walkApply, walkDestroy:
|
||||
log.Printf("[TRACE] NodeApplyableProvider: configuring %s", n.Addr)
|
||||
return n.ConfigureProvider(ctx, evalCtx, providerKey, provider, false)
|
||||
case walkImport:
|
||||
log.Printf("[TRACE] NodeApplyableProvider: configuring %s (requiring that configuration is wholly known)", n.Addr)
|
||||
return n.ConfigureProvider(ctx, evalCtx, providerKey, provider, true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx EvalContext, providerKey addrs.InstanceKey, provider providers.Interface) tfdiags.Diagnostics {
|
||||
func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx EvalContext, instance providers.Unconfigured, providerKey addrs.InstanceKey, data InstanceKeyEvalData) tfdiags.Diagnostics {
|
||||
_, span := tracing.Tracer().Start(
|
||||
ctx, "Validate provider configuration",
|
||||
tracing.SpanAttributes(
|
||||
|
|
@ -189,14 +150,14 @@ func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx Ev
|
|||
return nil
|
||||
}
|
||||
|
||||
schemaResp := provider.GetProviderSchema(ctx)
|
||||
diags := schemaResp.Diagnostics.InConfigBody(configBody, n.Addr.InstanceString(providerKey))
|
||||
schema, schemaDiags := evalCtx.Providers().GetProviderSchema(ctx, n.Addr.Provider)
|
||||
diags := schemaDiags.InConfigBody(configBody, n.Addr.InstanceString(providerKey))
|
||||
if diags.HasErrors() {
|
||||
tracing.SetSpanError(span, diags)
|
||||
return diags
|
||||
}
|
||||
|
||||
configSchema := schemaResp.Provider.Block
|
||||
configSchema := schema.Provider.Block
|
||||
if configSchema == nil {
|
||||
// Should never happen in real code, but often comes up in tests where
|
||||
// mock schemas are being used that tend to be incomplete.
|
||||
|
|
@ -204,11 +165,6 @@ func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx Ev
|
|||
configSchema = &configschema.Block{}
|
||||
}
|
||||
|
||||
data := EvalDataForNoInstanceKey
|
||||
if n.Config != nil && n.Config.Instances != nil {
|
||||
data = n.Config.Instances[providerKey]
|
||||
}
|
||||
|
||||
configVal, _, evalDiags := evalCtx.EvaluateBlock(ctx, configBody, configSchema, nil, data)
|
||||
if evalDiags.HasErrors() {
|
||||
tracing.SetSpanError(span, diags)
|
||||
|
|
@ -224,7 +180,7 @@ func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx Ev
|
|||
Config: unmarkedConfigVal,
|
||||
}
|
||||
|
||||
validateResp := provider.ValidateProviderConfig(ctx, req)
|
||||
validateResp := instance.ValidateProviderConfig(ctx, req)
|
||||
diags = diags.Append(validateResp.Diagnostics.InConfigBody(configBody, n.Addr.InstanceString(providerKey)))
|
||||
|
||||
tracing.SetSpanError(span, diags)
|
||||
|
|
@ -234,7 +190,7 @@ func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx Ev
|
|||
// ConfigureProvider configures a provider that is already initialized and retrieved.
|
||||
// If verifyConfigIsKnown is true, ConfigureProvider will return an error if the
|
||||
// provider configVal is not wholly known and is meant only for use during import.
|
||||
func (n *NodeApplyableProvider) ConfigureProvider(ctx context.Context, evalCtx EvalContext, providerKey addrs.InstanceKey, provider providers.Interface, verifyConfigIsKnown bool) tfdiags.Diagnostics {
|
||||
func (n *NodeApplyableProvider) ConfigureProvider(ctx context.Context, evalCtx EvalContext, providerKey addrs.InstanceKey, data InstanceKeyEvalData, verifyConfigIsKnown bool) tfdiags.Diagnostics {
|
||||
_, span := tracing.Tracer().Start(
|
||||
ctx, "Configure provider",
|
||||
tracing.SpanAttributes(
|
||||
|
|
@ -247,25 +203,23 @@ func (n *NodeApplyableProvider) ConfigureProvider(ctx context.Context, evalCtx E
|
|||
|
||||
if n.Config != nil && n.Config.IsMocked {
|
||||
// Mocked for testing
|
||||
return nil
|
||||
instance, diags := evalCtx.Providers().NewProvider(ctx, n.Addr.Provider)
|
||||
n.instances[providerKey] = instance
|
||||
return diags
|
||||
}
|
||||
|
||||
config := n.ProviderConfig()
|
||||
|
||||
configBody := buildProviderConfig(ctx, evalCtx, n.Addr, config)
|
||||
|
||||
resp := provider.GetProviderSchema(ctx)
|
||||
diags := resp.Diagnostics.InConfigBody(configBody, n.Addr.InstanceString(providerKey))
|
||||
schema, schemaDiags := evalCtx.Providers().GetProviderSchema(ctx, n.Addr.Provider)
|
||||
diags := schemaDiags.InConfigBody(configBody, n.Addr.InstanceString(providerKey))
|
||||
if diags.HasErrors() {
|
||||
tracing.SetSpanError(span, diags)
|
||||
return diags
|
||||
}
|
||||
|
||||
configSchema := resp.Provider.Block
|
||||
data := EvalDataForNoInstanceKey
|
||||
if n.Config != nil && n.Config.Instances != nil {
|
||||
data = n.Config.Instances[providerKey]
|
||||
}
|
||||
configSchema := schema.Provider.Block
|
||||
|
||||
configVal, configBody, evalDiags := evalCtx.EvaluateBlock(ctx, configBody, configSchema, nil, data)
|
||||
diags = diags.Append(evalDiags)
|
||||
|
|
@ -285,20 +239,11 @@ func (n *NodeApplyableProvider) ConfigureProvider(ctx context.Context, evalCtx E
|
|||
return diags
|
||||
}
|
||||
|
||||
// If our config value contains any marked values, ensure those are
|
||||
// stripped out before sending this to the provider
|
||||
unmarkedConfigVal, _ := configVal.UnmarkDeep()
|
||||
provider, newDiags := evalCtx.Providers().NewConfiguredProvider(ctx, n.Addr.Provider, configVal)
|
||||
diags = diags.Append(newDiags.InConfigBody(configBody, n.Addr.InstanceString(providerKey)))
|
||||
|
||||
// Allow the provider to validate and insert any defaults into the full
|
||||
// configuration.
|
||||
req := providers.ValidateProviderConfigRequest{
|
||||
Config: unmarkedConfigVal,
|
||||
}
|
||||
n.instances[providerKey] = provider
|
||||
|
||||
// ValidateProviderConfig is only used for validation. We are intentionally
|
||||
// ignoring the PreparedConfig field to maintain existing behavior.
|
||||
validateResp := provider.ValidateProviderConfig(ctx, req)
|
||||
diags = diags.Append(validateResp.Diagnostics.InConfigBody(configBody, n.Addr.InstanceString(providerKey)))
|
||||
if diags.HasErrors() && config == nil {
|
||||
// If there isn't an explicit "provider" block in the configuration,
|
||||
// this error message won't be very clear. Add some detail to the error
|
||||
|
|
@ -315,29 +260,6 @@ func (n *NodeApplyableProvider) ConfigureProvider(ctx context.Context, evalCtx E
|
|||
return diags
|
||||
}
|
||||
|
||||
// If the provider returns something different, log a warning to help
|
||||
// indicate to provider developers that the value is not used.
|
||||
preparedCfg := validateResp.PreparedConfig
|
||||
if preparedCfg != cty.NilVal && !preparedCfg.IsNull() && !preparedCfg.RawEquals(unmarkedConfigVal) {
|
||||
log.Printf("[WARN] ValidateProviderConfig from %q changed the config value, but that value is unused", n.Addr)
|
||||
}
|
||||
|
||||
configResp := provider.ConfigureProvider(ctx, providers.ConfigureProviderRequest{
|
||||
TerraformVersion: version.String(),
|
||||
Config: unmarkedConfigVal,
|
||||
})
|
||||
diags = diags.Append(configResp.Diagnostics.InConfigBody(configBody, n.Addr.InstanceString(providerKey)))
|
||||
if diags.HasErrors() && config == nil {
|
||||
// If there isn't an explicit "provider" block in the configuration,
|
||||
// this error message won't be very clear. Add some detail to the error
|
||||
// message in this case.
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Invalid provider configuration",
|
||||
fmt.Sprintf(providerConfigErr, n.Addr.Provider),
|
||||
))
|
||||
}
|
||||
tracing.SetSpanError(span, diags)
|
||||
return diags
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ func (n *NodeEvalableProvider) Close(ctx context.Context) error {
|
|||
|
||||
// GraphNodeExecutable
|
||||
func (n *NodeEvalableProvider) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||
var err error
|
||||
n.instance, err = evalCtx.InitProvider(ctx, n.Addr, addrs.NoKey)
|
||||
return diags.Append(err)
|
||||
n.instance, diags = evalCtx.Providers().NewProvider(ctx, n.Addr.Provider)
|
||||
return diags
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ func TestNodeApplyableProviderExecute(t *testing.T) {
|
|||
Config: config,
|
||||
}}
|
||||
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
evalCtx.ProviderInputValues = map[string]cty.Value{
|
||||
"pw": cty.StringVal("so secret"),
|
||||
|
|
@ -98,7 +99,8 @@ func TestNodeApplyableProviderExecute_unknownImport(t *testing.T) {
|
|||
Config: config,
|
||||
}}
|
||||
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
|
||||
diags := n.Execute(t.Context(), evalCtx, walkImport)
|
||||
|
|
@ -132,7 +134,8 @@ func TestNodeApplyableProviderExecute_unknownApply(t *testing.T) {
|
|||
Addr: providerAddr,
|
||||
Config: config,
|
||||
}}
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
|
||||
if err := n.Execute(t.Context(), evalCtx, walkApply); err != nil {
|
||||
|
|
@ -170,7 +173,8 @@ func TestNodeApplyableProviderExecute_sensitive(t *testing.T) {
|
|||
Config: config,
|
||||
}}
|
||||
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
if err := n.Execute(t.Context(), evalCtx, walkApply); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
|
@ -207,7 +211,8 @@ func TestNodeApplyableProviderExecute_sensitiveValidate(t *testing.T) {
|
|||
Config: config,
|
||||
}}
|
||||
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
if err := n.Execute(t.Context(), evalCtx, walkValidate); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
|
@ -249,7 +254,8 @@ func TestNodeApplyableProviderExecute_emptyValidate(t *testing.T) {
|
|||
Config: config,
|
||||
}}
|
||||
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
if err := n.Execute(t.Context(), evalCtx, walkValidate); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
|
@ -261,6 +267,7 @@ func TestNodeApplyableProviderExecute_emptyValidate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNodeApplyableProvider_Validate(t *testing.T) {
|
||||
providerAddr := mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
provider := mockProviderWithConfigSchema(&configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"region": {
|
||||
|
|
@ -269,7 +276,8 @@ func TestNodeApplyableProvider_Validate(t *testing.T) {
|
|||
},
|
||||
},
|
||||
})
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
|
|
@ -282,12 +290,12 @@ func TestNodeApplyableProvider_Validate(t *testing.T) {
|
|||
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
Config: config,
|
||||
},
|
||||
}
|
||||
|
||||
diags := node.ValidateProvider(t.Context(), evalCtx, addrs.NoKey, provider)
|
||||
diags := node.ValidateProvider(t.Context(), evalCtx, provider, addrs.NoKey, EvalDataForNoInstanceKey)
|
||||
if diags.HasErrors() {
|
||||
t.Errorf("unexpected error with valid config: %s", diags.Err())
|
||||
}
|
||||
|
|
@ -303,12 +311,12 @@ func TestNodeApplyableProvider_Validate(t *testing.T) {
|
|||
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
Config: config,
|
||||
},
|
||||
}
|
||||
|
||||
diags := node.ValidateProvider(t.Context(), evalCtx, addrs.NoKey, provider)
|
||||
diags := node.ValidateProvider(t.Context(), evalCtx, provider, addrs.NoKey, EvalDataForNoInstanceKey)
|
||||
if !diags.HasErrors() {
|
||||
t.Error("missing expected error with invalid config")
|
||||
}
|
||||
|
|
@ -317,11 +325,11 @@ func TestNodeApplyableProvider_Validate(t *testing.T) {
|
|||
t.Run("empty config", func(t *testing.T) {
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
},
|
||||
}
|
||||
|
||||
diags := node.ValidateProvider(t.Context(), evalCtx, addrs.NoKey, provider)
|
||||
diags := node.ValidateProvider(t.Context(), evalCtx, provider, addrs.NoKey, EvalDataForNoInstanceKey)
|
||||
if diags.HasErrors() {
|
||||
t.Errorf("unexpected error with empty config: %s", diags.Err())
|
||||
}
|
||||
|
|
@ -333,6 +341,7 @@ func TestNodeApplyableProvider_Validate(t *testing.T) {
|
|||
// TestNodeApplyableProvider_ConfigProvider_config_fn_err for
|
||||
// providers.ConfigureProviderRequest responses.
|
||||
func TestNodeApplyableProvider_ConfigProvider(t *testing.T) {
|
||||
providerAddr := mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
provider := mockProviderWithConfigSchema(&configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"region": {
|
||||
|
|
@ -351,7 +360,8 @@ func TestNodeApplyableProvider_ConfigProvider(t *testing.T) {
|
|||
}
|
||||
return
|
||||
}
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
|
|
@ -364,12 +374,13 @@ func TestNodeApplyableProvider_ConfigProvider(t *testing.T) {
|
|||
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
Config: config,
|
||||
},
|
||||
instances: map[addrs.InstanceKey]providers.Configured{},
|
||||
}
|
||||
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, provider, false)
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, EvalDataForNoInstanceKey, false)
|
||||
if diags.HasErrors() {
|
||||
t.Errorf("unexpected error with valid config: %s", diags.Err())
|
||||
}
|
||||
|
|
@ -378,11 +389,12 @@ func TestNodeApplyableProvider_ConfigProvider(t *testing.T) {
|
|||
t.Run("missing required config (no config at all)", func(t *testing.T) {
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
},
|
||||
instances: map[addrs.InstanceKey]providers.Configured{},
|
||||
}
|
||||
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, provider, false)
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, EvalDataForNoInstanceKey, false)
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("missing expected error with nil config")
|
||||
}
|
||||
|
|
@ -398,12 +410,13 @@ func TestNodeApplyableProvider_ConfigProvider(t *testing.T) {
|
|||
}
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
Config: config,
|
||||
},
|
||||
instances: map[addrs.InstanceKey]providers.Configured{},
|
||||
}
|
||||
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, provider, false)
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, EvalDataForNoInstanceKey, false)
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("missing expected error with invalid config")
|
||||
}
|
||||
|
|
@ -416,6 +429,7 @@ func TestNodeApplyableProvider_ConfigProvider(t *testing.T) {
|
|||
|
||||
// This test is similar to TestNodeApplyableProvider_ConfigProvider, but tests responses from the providers.ConfigureProviderRequest
|
||||
func TestNodeApplyableProvider_ConfigProvider_config_fn_err(t *testing.T) {
|
||||
providerAddr := mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`)
|
||||
provider := mockProviderWithConfigSchema(&configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"region": {
|
||||
|
|
@ -424,7 +438,8 @@ func TestNodeApplyableProvider_ConfigProvider_config_fn_err(t *testing.T) {
|
|||
},
|
||||
},
|
||||
})
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
// For this test, provider.PrepareConfigFn will succeed every time but the
|
||||
// ctx.ConfigureProviderFn will return an error if a value is not found.
|
||||
|
|
@ -459,12 +474,13 @@ func TestNodeApplyableProvider_ConfigProvider_config_fn_err(t *testing.T) {
|
|||
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
Config: config,
|
||||
},
|
||||
instances: map[addrs.InstanceKey]providers.Configured{},
|
||||
}
|
||||
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, provider, false)
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, EvalDataForNoInstanceKey, false)
|
||||
if diags.HasErrors() {
|
||||
t.Errorf("unexpected error with valid config: %s", diags.Err())
|
||||
}
|
||||
|
|
@ -473,11 +489,12 @@ func TestNodeApplyableProvider_ConfigProvider_config_fn_err(t *testing.T) {
|
|||
t.Run("missing required config (no config at all)", func(t *testing.T) {
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
},
|
||||
instances: map[addrs.InstanceKey]providers.Configured{},
|
||||
}
|
||||
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, provider, false)
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, EvalDataForNoInstanceKey, false)
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("missing expected error with nil config")
|
||||
}
|
||||
|
|
@ -493,12 +510,13 @@ func TestNodeApplyableProvider_ConfigProvider_config_fn_err(t *testing.T) {
|
|||
}
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: mustProviderConfig(`provider["registry.opentofu.org/hashicorp/aws"]`),
|
||||
Addr: providerAddr,
|
||||
Config: config,
|
||||
},
|
||||
instances: map[addrs.InstanceKey]providers.Configured{},
|
||||
}
|
||||
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, provider, false)
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, EvalDataForNoInstanceKey, false)
|
||||
if !diags.HasErrors() {
|
||||
t.Fatal("missing expected error with invalid config")
|
||||
}
|
||||
|
|
@ -516,15 +534,17 @@ func TestGetSchemaError(t *testing.T) {
|
|||
}
|
||||
|
||||
providerAddr := mustProviderConfig(`provider["terraform.io/some/provider"]`)
|
||||
evalCtx := &MockEvalContext{InitProviderProvider: provider}
|
||||
evalCtx := &MockEvalContext{}
|
||||
evalCtx.installProvider(providerAddr.Provider, provider)
|
||||
evalCtx.installSimpleEval()
|
||||
node := NodeApplyableProvider{
|
||||
NodeAbstractProvider: &NodeAbstractProvider{
|
||||
Addr: providerAddr,
|
||||
},
|
||||
instances: map[addrs.InstanceKey]providers.Configured{},
|
||||
}
|
||||
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, provider, false)
|
||||
diags := node.ConfigureProvider(t.Context(), evalCtx, addrs.NoKey, EvalDataForNoInstanceKey, false)
|
||||
for _, d := range diags {
|
||||
desc := d.Description()
|
||||
if desc.Address != providerAddr.String() {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plans/objchange"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/shared"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -2644,13 +2643,7 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(ctx context.Context, ev
|
|||
for _, prov := range provs {
|
||||
log.Printf("[TRACE] applyProvisioners: provisioning %s with %q", n.Addr, prov.Type)
|
||||
|
||||
// Get the provisioner
|
||||
provisioner, err := evalCtx.Provisioner(prov.Type)
|
||||
if err != nil {
|
||||
return diags.Append(err)
|
||||
}
|
||||
|
||||
schema, err := evalCtx.ProvisionerSchema(prov.Type)
|
||||
schema, err := evalCtx.Provisioners().ProvisionerSchema(prov.Type)
|
||||
if err != nil {
|
||||
// This error probably won't be a great diagnostic, but in practice
|
||||
// we typically catch this problem long before we get here, so
|
||||
|
|
@ -2750,12 +2743,15 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(ctx context.Context, ev
|
|||
}
|
||||
|
||||
output := CallbackUIOutput{OutputFn: outputFn}
|
||||
resp := provisioner.ProvisionResource(provisioners.ProvisionResourceRequest{
|
||||
Config: unmarkedConfig,
|
||||
Connection: unmarkedConnInfo,
|
||||
UIOutput: &output,
|
||||
})
|
||||
applyDiags := resp.Diagnostics.InConfigBody(prov.Config, n.Addr.String())
|
||||
|
||||
resp := evalCtx.Provisioners().ProvisionResource(
|
||||
ctx,
|
||||
prov.Type,
|
||||
unmarkedConfig,
|
||||
unmarkedConnInfo,
|
||||
&output,
|
||||
)
|
||||
applyDiags := resp.InConfigBody(prov.Config, n.Addr.String())
|
||||
|
||||
// Call post hook
|
||||
hookErr := evalCtx.Hook(func(h Hook) (HookAction, error) {
|
||||
|
|
@ -3181,9 +3177,9 @@ func (n *NodeAbstractResourceInstance) getProvider(ctx context.Context, evalCtx
|
|||
|
||||
// Not all callers require a schema, so we will leave checking for a nil
|
||||
// schema to the callers.
|
||||
schema, err := evalCtx.ProviderSchema(ctx, n.ResolvedProvider.ProviderConfig)
|
||||
if err != nil {
|
||||
return nil, providers.ProviderSchema{}, fmt.Errorf("failed to read schema for provider %s: %w", n.ResolvedProvider.ProviderConfig, err)
|
||||
schema, schemaDiags := evalCtx.Providers().GetProviderSchema(ctx, n.ResolvedProvider.ProviderConfig.Provider)
|
||||
if schemaDiags.HasErrors() {
|
||||
return nil, providers.ProviderSchema{}, fmt.Errorf("failed to read schema for provider %s: %w", n.ResolvedProvider.ProviderConfig, schemaDiags.Err())
|
||||
}
|
||||
|
||||
var isOverridden bool
|
||||
|
|
@ -3220,7 +3216,7 @@ func (n *NodeAbstractResourceInstance) getProvider(ctx context.Context, evalCtx
|
|||
return provider, schema, err
|
||||
}
|
||||
|
||||
return underlyingProvider, schema, err
|
||||
return underlyingProvider, schema, nil
|
||||
}
|
||||
|
||||
func (n *NodeAbstractResourceInstance) applyEphemeralResource(ctx context.Context, evalCtx EvalContext) (*states.ResourceInstanceObject, instances.RepetitionData, tfdiags.Diagnostics) {
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ func TestNodeAbstractResourceInstance_WriteResourceInstanceState(t *testing.T) {
|
|||
ResolvedProvider: mustResolvedProviderInRoot("aws", mockProvider),
|
||||
},
|
||||
}
|
||||
evalCtx.ProviderSchemaSchema = mockProvider.GetProviderSchema(t.Context())
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("aws"), mockProvider)
|
||||
|
||||
err := node.writeResourceInstanceState(t.Context(), evalCtx, obj, workingState)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -197,12 +197,14 @@ func getMockProviderForReadResourceInstanceState() *MockProvider {
|
|||
ResourceTypes: map[string]providers.Schema{
|
||||
"aws_instance": constructProviderSchemaForTesting(map[string]*configschema.Attribute{
|
||||
"id": {
|
||||
Type: cty.String,
|
||||
Type: cty.String,
|
||||
Computed: true,
|
||||
},
|
||||
}),
|
||||
"aws_instance0": constructProviderSchemaForTesting(map[string]*configschema.Attribute{
|
||||
"id": {
|
||||
Type: cty.String,
|
||||
Type: cty.String,
|
||||
Computed: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
|
@ -322,8 +324,8 @@ func TestNodeAbstractResource_ReadResourceInstanceState(t *testing.T) {
|
|||
evalCtx := new(MockEvalContext)
|
||||
evalCtx.StateState = test.State.SyncWrapper()
|
||||
evalCtx.PathPath = addrs.RootModuleInstance
|
||||
evalCtx.ProviderSchemaSchema = test.Provider.GetProviderSchema(t.Context())
|
||||
evalCtx.MoveResultsResults = test.MoveResults
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("aws"), test.Provider)
|
||||
test.Node.ResolvedProvider = mustResolvedProviderInRoot("aws", test.Provider)
|
||||
|
||||
got, readDiags := test.Node.readResourceInstanceState(t.Context(), evalCtx, test.Node.Addr)
|
||||
|
|
@ -337,7 +339,7 @@ func TestNodeAbstractResource_ReadResourceInstanceState(t *testing.T) {
|
|||
return
|
||||
}
|
||||
if readDiags.HasErrors() {
|
||||
t.Fatalf("[%s] Got err: %#v", test.Name, readDiags.Err())
|
||||
t.Fatalf("[%s] Got err: %s", test.Name, readDiags.Err())
|
||||
}
|
||||
|
||||
expected := test.ExpectedInstanceId
|
||||
|
|
@ -369,8 +371,8 @@ func TestNodeAbstractResource_ReadResourceInstanceState(t *testing.T) {
|
|||
evalCtx := new(MockEvalContext)
|
||||
evalCtx.StateState = test.State.SyncWrapper()
|
||||
evalCtx.PathPath = addrs.RootModuleInstance
|
||||
evalCtx.ProviderSchemaSchema = test.Provider.GetProviderSchema(t.Context())
|
||||
evalCtx.MoveResultsResults = test.MoveResults
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("aws"), test.Provider)
|
||||
test.Node.ResolvedProvider = mustResolvedProviderInRoot("aws", test.Provider)
|
||||
|
||||
key := states.DeposedKey("00000001") // shim from legacy state assigns 0th deposed index this key
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ func TestNodeDestroyDeposedResourceInstanceObject_WriteResourceInstanceState(t *
|
|||
},
|
||||
},
|
||||
})
|
||||
evalCtx.ProviderSchemaSchema = mockProvider.GetProviderSchema(t.Context())
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("aws"), mockProvider)
|
||||
|
||||
obj := &states.ResourceInstanceObject{
|
||||
Value: cty.ObjectVal(map[string]cty.Value{
|
||||
|
|
@ -300,10 +300,10 @@ aws_instance.foo: (1 deposed)
|
|||
func TestNodeDestroyDeposedResourceInstanceObject_ExecuteMissingState(t *testing.T) {
|
||||
p := simpleMockProvider()
|
||||
evalCtx := &MockEvalContext{
|
||||
StateState: states.NewState().SyncWrapper(),
|
||||
ProviderSchemaSchema: p.GetProviderSchema(t.Context()),
|
||||
ChangesChanges: plans.NewChanges().SyncWrapper(),
|
||||
StateState: states.NewState().SyncWrapper(),
|
||||
ChangesChanges: plans.NewChanges().SyncWrapper(),
|
||||
}
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
node := NodeDestroyDeposedResourceInstanceObject{
|
||||
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
|
||||
|
|
@ -391,13 +391,15 @@ func initMockEvalContext(ctx context.Context, resourceAddrs string, deposedKey s
|
|||
"id": cty.StringVal("bar"),
|
||||
}),
|
||||
}
|
||||
return &MockEvalContext{
|
||||
PrevRunStateState: state.DeepCopy().SyncWrapper(),
|
||||
RefreshStateState: state.DeepCopy().SyncWrapper(),
|
||||
StateState: state.SyncWrapper(),
|
||||
ProviderSchemaSchema: schema,
|
||||
ChangesChanges: plans.NewChanges().SyncWrapper(),
|
||||
}, p
|
||||
evalCtx := &MockEvalContext{
|
||||
PrevRunStateState: state.DeepCopy().SyncWrapper(),
|
||||
RefreshStateState: state.DeepCopy().SyncWrapper(),
|
||||
StateState: state.SyncWrapper(),
|
||||
ChangesChanges: plans.NewChanges().SyncWrapper(),
|
||||
}
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
return evalCtx, p
|
||||
}
|
||||
|
||||
func assertDiags(t *testing.T, got, want tfdiags.Diagnostics) {
|
||||
|
|
|
|||
|
|
@ -223,9 +223,9 @@ func TestNodeResourcePlanOrphan_Execute(t *testing.T) {
|
|||
RefreshStateState: state.DeepCopy().SyncWrapper(),
|
||||
PrevRunStateState: state.DeepCopy().SyncWrapper(),
|
||||
InstanceExpanderExpander: instances.NewExpander(),
|
||||
ProviderSchemaSchema: schema,
|
||||
ChangesChanges: plans.NewChanges().SyncWrapper(),
|
||||
}
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
node := NodePlannableResourceInstanceOrphan{
|
||||
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
|
||||
|
|
@ -279,6 +279,13 @@ func TestNodeResourcePlanOrphanExecute_alreadyDeleted(t *testing.T) {
|
|||
changes := plans.NewChanges()
|
||||
|
||||
p := simpleMockProvider()
|
||||
p.GetProviderSchemaResponse = &providers.ProviderSchema{
|
||||
ResourceTypes: map[string]providers.Schema{
|
||||
"test_object": {
|
||||
Block: simpleTestSchema(),
|
||||
},
|
||||
},
|
||||
}
|
||||
p.ConfigureProvider(t.Context(), providers.ConfigureProviderRequest{})
|
||||
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
||||
NewState: cty.NullVal(p.GetProviderSchemaResponse.ResourceTypes["test_string"].Block.ImpliedType()),
|
||||
|
|
@ -288,15 +295,9 @@ func TestNodeResourcePlanOrphanExecute_alreadyDeleted(t *testing.T) {
|
|||
RefreshStateState: refreshState.SyncWrapper(),
|
||||
PrevRunStateState: prevRunState.SyncWrapper(),
|
||||
InstanceExpanderExpander: instances.NewExpander(),
|
||||
ProviderSchemaSchema: providers.ProviderSchema{
|
||||
ResourceTypes: map[string]providers.Schema{
|
||||
"test_object": {
|
||||
Block: simpleTestSchema(),
|
||||
},
|
||||
},
|
||||
},
|
||||
ChangesChanges: changes.SyncWrapper(),
|
||||
ChangesChanges: changes.SyncWrapper(),
|
||||
}
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
node := NodePlannableResourceInstanceOrphan{
|
||||
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
|
||||
|
|
@ -358,6 +359,13 @@ func TestNodeResourcePlanOrphanExecute_deposed(t *testing.T) {
|
|||
changes := plans.NewChanges()
|
||||
|
||||
p := simpleMockProvider()
|
||||
p.GetProviderSchemaResponse = &providers.ProviderSchema{
|
||||
ResourceTypes: map[string]providers.Schema{
|
||||
"test_object": {
|
||||
Block: simpleTestSchema(),
|
||||
},
|
||||
},
|
||||
}
|
||||
p.ConfigureProvider(t.Context(), providers.ConfigureProviderRequest{})
|
||||
p.ReadResourceResponse = &providers.ReadResourceResponse{
|
||||
NewState: cty.NullVal(p.GetProviderSchemaResponse.ResourceTypes["test_string"].Block.ImpliedType()),
|
||||
|
|
@ -367,15 +375,9 @@ func TestNodeResourcePlanOrphanExecute_deposed(t *testing.T) {
|
|||
RefreshStateState: refreshState.SyncWrapper(),
|
||||
PrevRunStateState: prevRunState.SyncWrapper(),
|
||||
InstanceExpanderExpander: instances.NewExpander(),
|
||||
ProviderSchemaSchema: providers.ProviderSchema{
|
||||
ResourceTypes: map[string]providers.Schema{
|
||||
"test_object": {
|
||||
Block: simpleTestSchema(),
|
||||
},
|
||||
},
|
||||
},
|
||||
ChangesChanges: changes.SyncWrapper(),
|
||||
ChangesChanges: changes.SyncWrapper(),
|
||||
}
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
node := NodePlannableResourceInstanceOrphan{
|
||||
NodeAbstractResourceInstance: &NodeAbstractResourceInstance{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/instances"
|
||||
"github.com/opentofu/opentofu/internal/lang"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
"github.com/opentofu/opentofu/internal/tracing"
|
||||
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||
|
|
@ -130,16 +129,7 @@ func (n *NodeValidatableResource) Execute(ctx context.Context, evalCtx EvalConte
|
|||
func (n *NodeValidatableResource) validateProvisioner(ctx context.Context, evalCtx EvalContext, p *configs.Provisioner) tfdiags.Diagnostics {
|
||||
var diags tfdiags.Diagnostics
|
||||
|
||||
provisioner, err := evalCtx.Provisioner(p.Type)
|
||||
if err != nil {
|
||||
diags = diags.Append(err)
|
||||
return diags
|
||||
}
|
||||
|
||||
if provisioner == nil {
|
||||
return diags.Append(fmt.Errorf("provisioner %s not initialized", p.Type))
|
||||
}
|
||||
provisionerSchema, err := evalCtx.ProvisionerSchema(p.Type)
|
||||
provisionerSchema, err := evalCtx.Provisioners().ProvisionerSchema(p.Type)
|
||||
if err != nil {
|
||||
return diags.Append(fmt.Errorf("failed to read schema for provisioner %s: %w", p.Type, err))
|
||||
}
|
||||
|
|
@ -158,12 +148,8 @@ func (n *NodeValidatableResource) validateProvisioner(ctx context.Context, evalC
|
|||
|
||||
// Use unmarked value for validate request
|
||||
unmarkedConfigVal, _ := configVal.UnmarkDeep()
|
||||
req := provisioners.ValidateProvisionerConfigRequest{
|
||||
Config: unmarkedConfigVal,
|
||||
}
|
||||
|
||||
resp := provisioner.ValidateProvisionerConfig(req)
|
||||
diags = diags.Append(resp.Diagnostics)
|
||||
resp := evalCtx.Provisioners().ValidateProvisionerConfig(ctx, p.Type, unmarkedConfigVal)
|
||||
diags = diags.Append(resp)
|
||||
|
||||
if p.Connection != nil {
|
||||
// We can't comprehensively validate the connection config since its
|
||||
|
|
@ -192,8 +178,8 @@ func (n *NodeValidatableResource) validateResource(ctx context.Context, evalCtx
|
|||
if diags.HasErrors() {
|
||||
return diags
|
||||
}
|
||||
providerSchema, err := evalCtx.ProviderSchema(ctx, n.ResolvedProvider.ProviderConfig)
|
||||
diags = diags.Append(err)
|
||||
providerSchema, moreDiags := evalCtx.Providers().GetProviderSchema(ctx, n.ResolvedProvider.ProviderConfig.Provider)
|
||||
diags = diags.Append(moreDiags)
|
||||
if diags.HasErrors() {
|
||||
return diags
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/configs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/lang/marks"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/provisioners"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -27,9 +28,11 @@ func TestNodeValidatableResource_ValidateProvisioner_valid(t *testing.T) {
|
|||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
mp := &MockProvisioner{}
|
||||
ps := &configschema.Block{}
|
||||
ctx.ProvisionerSchemaSchema = ps
|
||||
ctx.ProvisionerProvisioner = mp
|
||||
mp.GetSchemaResponse = provisioners.GetSchemaResponse{Provisioner: &configschema.Block{}}
|
||||
|
||||
ctx.ProvisionersProvisioners = plugins.NewLibrary(nil, map[string]provisioners.Factory{
|
||||
"baz": func() (provisioners.Interface, error) { return mp, nil },
|
||||
}).NewProvisionerManager()
|
||||
|
||||
pc := &configs.Provisioner{
|
||||
Type: "baz",
|
||||
|
|
@ -70,9 +73,10 @@ func TestNodeValidatableResource_ValidateProvisioner__warning(t *testing.T) {
|
|||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
mp := &MockProvisioner{}
|
||||
ps := &configschema.Block{}
|
||||
ctx.ProvisionerSchemaSchema = ps
|
||||
ctx.ProvisionerProvisioner = mp
|
||||
mp.GetSchemaResponse = provisioners.GetSchemaResponse{Provisioner: &configschema.Block{}}
|
||||
ctx.ProvisionersProvisioners = plugins.NewLibrary(nil, map[string]provisioners.Factory{
|
||||
"baz": func() (provisioners.Interface, error) { return mp, nil },
|
||||
}).NewProvisionerManager()
|
||||
|
||||
pc := &configs.Provisioner{
|
||||
Type: "baz",
|
||||
|
|
@ -116,9 +120,10 @@ func TestNodeValidatableResource_ValidateProvisioner__connectionInvalid(t *testi
|
|||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
mp := &MockProvisioner{}
|
||||
ps := &configschema.Block{}
|
||||
ctx.ProvisionerSchemaSchema = ps
|
||||
ctx.ProvisionerProvisioner = mp
|
||||
mp.GetSchemaResponse = provisioners.GetSchemaResponse{Provisioner: &configschema.Block{}}
|
||||
ctx.ProvisionersProvisioners = plugins.NewLibrary(nil, map[string]provisioners.Factory{
|
||||
"baz": func() (provisioners.Interface, error) { return mp, nil },
|
||||
}).NewProvisionerManager()
|
||||
|
||||
pc := &configs.Provisioner{
|
||||
Type: "baz",
|
||||
|
|
@ -196,7 +201,7 @@ func TestNodeValidatableResource_ValidateResource_managedResource(t *testing.T)
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
err := node.validateResource(t.Context(), ctx)
|
||||
if err != nil {
|
||||
|
|
@ -225,7 +230,7 @@ func TestNodeValidatableResource_ValidateResource_managedResourceCount(t *testin
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -296,7 +301,7 @@ func TestNodeValidatableResource_ValidateResource_ephemeralResource(t *testing.T
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
t.Run("no errors", func(t *testing.T) {
|
||||
mp.ValidateEphemeralConfigCalled = false
|
||||
|
|
@ -385,7 +390,7 @@ func TestNodeValidatableResource_ValidateResource_dataSource(t *testing.T) {
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
diags := node.validateResource(t.Context(), ctx)
|
||||
if diags.HasErrors() {
|
||||
|
|
@ -420,7 +425,7 @@ func TestNodeValidatableResource_ValidateResource_valid(t *testing.T) {
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
diags := node.validateResource(t.Context(), ctx)
|
||||
if diags.HasErrors() {
|
||||
|
|
@ -456,7 +461,7 @@ func TestNodeValidatableResource_ValidateResource_warningsAndErrorsPassedThrough
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
diags := node.validateResource(t.Context(), ctx)
|
||||
if !diags.HasErrors() {
|
||||
|
|
@ -517,8 +522,7 @@ func TestNodeValidatableResource_ValidateResource_invalidDependsOn(t *testing.T)
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
diags := node.validateResource(t.Context(), ctx)
|
||||
if diags.HasErrors() {
|
||||
|
|
@ -600,8 +604,7 @@ func TestNodeValidatableResource_ValidateResource_invalidIgnoreChangesNonexisten
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
diags := node.validateResource(t.Context(), ctx)
|
||||
if diags.HasErrors() {
|
||||
|
|
@ -682,8 +685,7 @@ func TestNodeValidatableResource_ValidateResource_invalidIgnoreChangesComputed(t
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
diags := node.validateResource(t.Context(), ctx)
|
||||
if diags.HasErrors() {
|
||||
|
|
@ -809,8 +811,7 @@ func TestNodeValidatableResource_ValidateResource_suggestion(t *testing.T) {
|
|||
|
||||
ctx := &MockEvalContext{}
|
||||
ctx.installSimpleEval()
|
||||
|
||||
ctx.ProviderSchemaSchema = mp.GetProviderSchema(t.Context())
|
||||
ctx.installProvider(addrs.NewDefaultProvider("test"), p)
|
||||
|
||||
diags := node.validateResource(t.Context(), ctx)
|
||||
if got, want := len(diags), 1; got != want {
|
||||
|
|
|
|||
|
|
@ -109,14 +109,14 @@ func loadProviderSchemas(ctx context.Context, config *configs.Config, state *sta
|
|||
for fqn := range schemas {
|
||||
wg.Go(func() {
|
||||
log.Printf("[TRACE] LoadSchemas: retrieving schema for provider type %q", fqn.String())
|
||||
schema, err := plugins.ProviderSchema(ctx, fqn)
|
||||
schema, schemaDiags := plugins.providers.GetProviderSchema(ctx, fqn)
|
||||
|
||||
// Ensure that we don't race on diags or schemas now that the hard work is done
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
if err != nil {
|
||||
diags = diags.Append(err)
|
||||
if schemaDiags.HasErrors() {
|
||||
diags = diags.Append(schemaDiags)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
)
|
||||
|
||||
|
|
@ -312,5 +313,5 @@ func schemaOnlyProvidersForTesting(schemas map[addrs.Provider]providers.Provider
|
|||
}
|
||||
}
|
||||
|
||||
return newContextPlugins(factories, nil)
|
||||
return newContextPlugins(plugins.NewLibrary(factories, nil))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/opentofu/opentofu/internal/addrs"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
)
|
||||
|
|
@ -90,9 +91,9 @@ func setupSkipTestDefaultContext(t *testing.T) (*Context, *MockProvider) {
|
|||
p.PlanResourceChangeFn = testDiffFn
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
return ctx, p
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ package tofu
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
|
|
@ -22,7 +21,6 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/lang/marks"
|
||||
"github.com/opentofu/opentofu/internal/moduletest"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
)
|
||||
|
|
@ -100,70 +98,21 @@ func (tc *TestContext) evaluate(state *states.SyncState, changes *plans.ChangesS
|
|||
PlanTimestamp: tc.Plan.Timestamp,
|
||||
// InstanceExpander is intentionally nil for test contexts
|
||||
// The GetModule function will fall back to using state/changes when it's nil
|
||||
InstanceExpander: nil,
|
||||
InstanceExpander: nil,
|
||||
},
|
||||
ModulePath: nil, // nil for the root module
|
||||
InstanceKeyData: EvalDataForNoInstanceKey,
|
||||
Operation: operation,
|
||||
}
|
||||
|
||||
var providerInstanceLock sync.Mutex
|
||||
providerInstances := make(map[addrs.Provider]providers.Interface)
|
||||
defer func() {
|
||||
for addr, inst := range providerInstances {
|
||||
log.Printf("[INFO] Shutting down test provider %s", addr)
|
||||
inst.Close(context.TODO())
|
||||
}
|
||||
}()
|
||||
|
||||
providerSupplier := func(addr addrs.Provider) providers.Interface {
|
||||
providerInstanceLock.Lock()
|
||||
defer providerInstanceLock.Unlock()
|
||||
|
||||
if inst, ok := providerInstances[addr]; ok {
|
||||
return inst
|
||||
}
|
||||
|
||||
factory, ok := tc.plugins.providerFactories[addr]
|
||||
if !ok {
|
||||
log.Printf("[WARN] Unable to find provider %s in test context", addr)
|
||||
providerInstances[addr] = nil
|
||||
return nil
|
||||
}
|
||||
log.Printf("[INFO] Starting test provider %s", addr)
|
||||
inst, err := factory()
|
||||
if err != nil {
|
||||
log.Printf("[WARN] Unable to start provider %s in test context", addr)
|
||||
providerInstances[addr] = nil
|
||||
return nil
|
||||
} else {
|
||||
log.Printf("[INFO] Shutting down test provider %s", addr)
|
||||
providerInstances[addr] = inst
|
||||
return inst
|
||||
}
|
||||
}
|
||||
|
||||
scope := &lang.Scope{
|
||||
Data: data,
|
||||
BaseDir: ".",
|
||||
PureOnly: operation != walkApply,
|
||||
PlanTimestamp: tc.Plan.Timestamp,
|
||||
ProviderFunctions: func(ctx context.Context, pf addrs.ProviderFunction, rng tfdiags.SourceRange) (*function.Function, tfdiags.Diagnostics) {
|
||||
// This is a simpler flow than what is allowed during normal exection.
|
||||
// We only support non-configured functions here.
|
||||
pr, ok := tc.Config.Module.ProviderRequirements.RequiredProviders[pf.ProviderName]
|
||||
if !ok {
|
||||
return nil, tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Unknown function provider",
|
||||
Detail: fmt.Sprintf("Provider %q does not exist within the required_providers of this module", pf.ProviderName),
|
||||
Subject: rng.ToHCL().Ptr(),
|
||||
})
|
||||
}
|
||||
|
||||
provider := providerSupplier(pr.Type)
|
||||
|
||||
return evalContextProviderFunction(ctx, provider, walkPlan, pf, rng)
|
||||
// TODO pass in tc.plugins
|
||||
return evalContextProviderFunction(ctx, nil, walkPlan, pf, rng)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/opentofu/opentofu/internal/lang/marks"
|
||||
"github.com/opentofu/opentofu/internal/moduletest"
|
||||
"github.com/opentofu/opentofu/internal/plans"
|
||||
"github.com/opentofu/opentofu/internal/plugins"
|
||||
"github.com/opentofu/opentofu/internal/providers"
|
||||
"github.com/opentofu/opentofu/internal/states"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
|
|
@ -373,9 +374,9 @@ run "test_case" {
|
|||
t.Run(name, func(t *testing.T) {
|
||||
config := testModuleInline(t, tc.configs)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(tc.provider),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
run := moduletest.Run{
|
||||
|
|
@ -569,9 +570,9 @@ run "test_case" {
|
|||
t.Run(name, func(t *testing.T) {
|
||||
config := testModuleInline(t, tc.configs)
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
Plugins: plugins.NewLibrary(map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(tc.provider),
|
||||
},
|
||||
}, nil),
|
||||
})
|
||||
|
||||
run := moduletest.Run{
|
||||
|
|
|
|||
|
|
@ -70,9 +70,9 @@ func (t *AttachSchemaTransformer) Transform(ctx context.Context, g *Graph) error
|
|||
providerFqn := tv.Provider()
|
||||
|
||||
// TODO: Plumb a useful context.Context through to here.
|
||||
schema, version, err := t.Plugins.ResourceTypeSchema(ctx, providerFqn, mode, typeName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read schema for %s in %s: %w", addr, providerFqn, err)
|
||||
schema, version, diags := t.Plugins.ResourceTypeSchema(ctx, providerFqn, mode, typeName)
|
||||
if diags.HasErrors() {
|
||||
return fmt.Errorf("failed to read schema for %s in %s: %w", addr, providerFqn, diags.Err())
|
||||
}
|
||||
if schema == nil {
|
||||
log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr)
|
||||
|
|
@ -85,9 +85,9 @@ func (t *AttachSchemaTransformer) Transform(ctx context.Context, g *Graph) error
|
|||
if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok {
|
||||
providerAddr := tv.ProviderAddr()
|
||||
// TODO: Plumb a useful context.Context through to here.
|
||||
schema, err := t.Plugins.ProviderConfigSchema(ctx, providerAddr.Provider)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read provider configuration schema for %s: %w", providerAddr.Provider, err)
|
||||
schema, diags := t.Plugins.ProviderConfigSchema(ctx, providerAddr.Provider)
|
||||
if diags.HasErrors() {
|
||||
return fmt.Errorf("failed to read provider configuration schema for %s: %w", providerAddr.Provider, diags.Err())
|
||||
}
|
||||
if schema == nil {
|
||||
log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr)
|
||||
|
|
|
|||
|
|
@ -67,23 +67,24 @@ func TestGraphNodeImportStateSubExecute(t *testing.T) {
|
|||
state := states.NewState()
|
||||
provider := testProvider("aws")
|
||||
provider.ConfigureProvider(t.Context(), providers.ConfigureProviderRequest{})
|
||||
evalCtx := &MockEvalContext{
|
||||
StateState: state.SyncWrapper(),
|
||||
ProviderSchemaSchema: providers.ProviderSchema{
|
||||
ResourceTypes: map[string]providers.Schema{
|
||||
"aws_instance": {
|
||||
Block: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"id": {
|
||||
Type: cty.String,
|
||||
Computed: true,
|
||||
},
|
||||
provider.GetProviderSchemaResponse = &providers.ProviderSchema{
|
||||
ResourceTypes: map[string]providers.Schema{
|
||||
"aws_instance": {
|
||||
Block: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"id": {
|
||||
Type: cty.String,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
evalCtx := &MockEvalContext{
|
||||
StateState: state.SyncWrapper(),
|
||||
}
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("aws"), provider)
|
||||
|
||||
importedResource := providers.ImportedResource{
|
||||
TypeName: "aws_instance",
|
||||
|
|
@ -124,18 +125,14 @@ func TestGraphNodeImportStateSubExecuteNull(t *testing.T) {
|
|||
}))
|
||||
return resp
|
||||
}
|
||||
|
||||
evalCtx := &MockEvalContext{
|
||||
StateState: state.SyncWrapper(),
|
||||
ProviderSchemaSchema: providers.ProviderSchema{
|
||||
ResourceTypes: map[string]providers.Schema{
|
||||
"aws_instance": {
|
||||
Block: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"id": {
|
||||
Type: cty.String,
|
||||
Computed: true,
|
||||
},
|
||||
provider.GetProviderSchemaResponse = &providers.ProviderSchema{
|
||||
ResourceTypes: map[string]providers.Schema{
|
||||
"aws_instance": {
|
||||
Block: &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"id": {
|
||||
Type: cty.String,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -143,6 +140,11 @@ func TestGraphNodeImportStateSubExecuteNull(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
evalCtx := &MockEvalContext{
|
||||
StateState: state.SyncWrapper(),
|
||||
}
|
||||
evalCtx.installProvider(addrs.NewDefaultProvider("aws"), provider)
|
||||
|
||||
importedResource := providers.ImportedResource{
|
||||
TypeName: "aws_instance",
|
||||
State: cty.ObjectVal(map[string]cty.Value{"id": cty.StringVal("bar")}),
|
||||
|
|
|
|||
|
|
@ -62,3 +62,12 @@ func String() string {
|
|||
}
|
||||
return Version
|
||||
}
|
||||
|
||||
// This ONLY represents what features OpenTofu currently intends to support from
|
||||
// providers which may change their behavior given a particular TerraformVersion.
|
||||
// It explicitly does NOT represent any sort of compatibility promise or guarantee.
|
||||
// This value should ONLY ever be used by the provider.ConfigureProvider call, any
|
||||
// other usage is WRONG and a PROGRAMMING ERROR.
|
||||
// This value should be carefully updated as we add OpenTofu support for new protocol
|
||||
// features.
|
||||
const VersionToImpersonateForProviders = "1.13.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue