mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Make backend.ConfigSchema accept a context (#776)
Signed-off-by: Marcin Wyszynski <marcin.pixie@gmail.com>
This commit is contained in:
parent
a6ebabfea6
commit
bda32938e4
@ -61,7 +61,7 @@ type Backend interface {
|
||||
//
|
||||
// This method does not have any side-effects for the backend and can
|
||||
// be safely used before configuring.
|
||||
ConfigSchema() *configschema.Block
|
||||
ConfigSchema(context.Context) *configschema.Block
|
||||
|
||||
// PrepareConfig checks the validity of the values in the given
|
||||
// configuration, and inserts any missing defaults, assuming that its
|
||||
|
@ -104,9 +104,9 @@ func NewWithBackend(backend backend.Backend) *Local {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Local) ConfigSchema() *configschema.Block {
|
||||
func (b *Local) ConfigSchema(ctx context.Context) *configschema.Block {
|
||||
if b.Backend != nil {
|
||||
return b.Backend.ConfigSchema()
|
||||
return b.Backend.ConfigSchema(ctx)
|
||||
}
|
||||
return &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
|
@ -4,6 +4,7 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -216,7 +217,7 @@ func (b backendWithStateStorageThatFailsRefresh) StateMgr(workspace string) (sta
|
||||
return &stateStorageThatFailsRefresh{}, nil
|
||||
}
|
||||
|
||||
func (b backendWithStateStorageThatFailsRefresh) ConfigSchema() *configschema.Block {
|
||||
func (b backendWithStateStorageThatFailsRefresh) ConfigSchema(context.Context) *configschema.Block {
|
||||
return &configschema.Block{}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ package pg
|
||||
// TF_ACC=1 GO111MODULE=on go test -v -mod=vendor -timeout=2m -parallel=4 github.com/opentofu/opentofu/backend/remote-state/pg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
@ -149,9 +150,11 @@ func TestBackendConfig(t *testing.T) {
|
||||
}
|
||||
defer dbCleaner.Query(fmt.Sprintf("DROP SCHEMA IF EXISTS %s CASCADE", schemaName))
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
b := New().(*Backend)
|
||||
schema := b.ConfigSchema()
|
||||
schema := b.ConfigSchema(ctx)
|
||||
spec := schema.DecoderSpec()
|
||||
obj, decDiags := hcldec.Decode(config, spec, nil)
|
||||
diags = diags.Append(decDiags)
|
||||
|
@ -48,7 +48,7 @@ type Backend struct {
|
||||
|
||||
// ConfigSchema returns a description of the expected configuration
|
||||
// structure for the receiving backend.
|
||||
func (b *Backend) ConfigSchema() *configschema.Block {
|
||||
func (b *Backend) ConfigSchema(context.Context) *configschema.Block {
|
||||
return &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"bucket": {
|
||||
|
@ -45,7 +45,7 @@ func ExpectDiagsEqual(expected tfdiags.Diagnostics) diagsValidator {
|
||||
|
||||
type diagsValidator func(*testing.T, tfdiags.Diagnostics)
|
||||
|
||||
// ExpectDiagsMatching returns a validator expeceting a single Diagnostic with fields matching the expectation
|
||||
// ExpectDiagsMatching returns a validator expecting a single Diagnostic with fields matching the expectation
|
||||
func ExpectDiagsMatching(severity tfdiags.Severity, summary matcher, detail matcher) diagsValidator {
|
||||
return func(t *testing.T, diags tfdiags.Diagnostics) {
|
||||
for _, d := range diags {
|
||||
@ -1841,7 +1841,9 @@ func setSharedConfigFile(filename string) {
|
||||
|
||||
func configureBackend(t *testing.T, config map[string]any) (*Backend, tfdiags.Diagnostics) {
|
||||
b := New().(*Backend)
|
||||
configSchema := populateSchema(t, b.ConfigSchema(), hcl2shim.HCL2ValueFromConfigValue(config))
|
||||
ctx := context.Background()
|
||||
|
||||
configSchema := populateSchema(t, b.ConfigSchema(ctx), hcl2shim.HCL2ValueFromConfigValue(config))
|
||||
|
||||
configSchema, diags := b.PrepareConfig(configSchema)
|
||||
|
||||
|
@ -127,9 +127,11 @@ func TestBackendConfig_InvalidRegion(t *testing.T) {
|
||||
}
|
||||
|
||||
for name, tc := range cases {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
b := New()
|
||||
configSchema := populateSchema(t, b.ConfigSchema(), hcl2shim.HCL2ValueFromConfigValue(tc.config))
|
||||
configSchema := populateSchema(t, b.ConfigSchema(ctx), hcl2shim.HCL2ValueFromConfigValue(tc.config))
|
||||
|
||||
configSchema, diags := b.PrepareConfig(configSchema)
|
||||
if len(diags) > 0 {
|
||||
@ -365,8 +367,10 @@ func TestBackendConfig_STSEndpoint(t *testing.T) {
|
||||
config["sts_endpoint"] = endpoint
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
b := New()
|
||||
configSchema := populateSchema(t, b.ConfigSchema(), hcl2shim.HCL2ValueFromConfigValue(config))
|
||||
configSchema := populateSchema(t, b.ConfigSchema(ctx), hcl2shim.HCL2ValueFromConfigValue(config))
|
||||
|
||||
configSchema, diags := b.PrepareConfig(configSchema)
|
||||
if len(diags) > 0 {
|
||||
@ -598,13 +602,15 @@ func TestBackendConfig_AssumeRole(t *testing.T) {
|
||||
testCase := testCase
|
||||
|
||||
t.Run(testCase.Description, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
closeSts, _, endpoint := mockdata.GetMockedAwsApiSession("STS", testCase.MockStsEndpoints)
|
||||
defer closeSts()
|
||||
|
||||
testCase.Config["sts_endpoint"] = endpoint
|
||||
|
||||
b := New()
|
||||
diags := b.Configure(populateSchema(t, b.ConfigSchema(), hcl2shim.HCL2ValueFromConfigValue(testCase.Config)))
|
||||
diags := b.Configure(populateSchema(t, b.ConfigSchema(ctx), hcl2shim.HCL2ValueFromConfigValue(testCase.Config)))
|
||||
|
||||
if diags.HasErrors() {
|
||||
for _, diag := range diags {
|
||||
@ -732,7 +738,9 @@ func TestBackendConfig_PrepareConfigValidation(t *testing.T) {
|
||||
|
||||
b := New()
|
||||
|
||||
_, valDiags := b.PrepareConfig(populateSchema(t, b.ConfigSchema(), tc.config))
|
||||
ctx := context.Background()
|
||||
|
||||
_, valDiags := b.PrepareConfig(populateSchema(t, b.ConfigSchema(ctx), tc.config))
|
||||
if tc.expectedErr != "" {
|
||||
if valDiags.Err() != nil {
|
||||
actualErr := valDiags.Err().Error()
|
||||
@ -801,7 +809,9 @@ func TestBackendConfig_PrepareConfigWithEnvVars(t *testing.T) {
|
||||
os.Setenv(k, v)
|
||||
}
|
||||
|
||||
_, valDiags := b.PrepareConfig(populateSchema(t, b.ConfigSchema(), tc.config))
|
||||
ctx := context.Background()
|
||||
|
||||
_, valDiags := b.PrepareConfig(populateSchema(t, b.ConfigSchema(ctx), tc.config))
|
||||
if tc.expectedErr != "" {
|
||||
if valDiags.Err() != nil {
|
||||
actualErr := valDiags.Err().Error()
|
||||
@ -904,7 +914,9 @@ func TestBackendSSECustomerKeyConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
b := New().(*Backend)
|
||||
diags := b.Configure(populateSchema(t, b.ConfigSchema(), hcl2shim.HCL2ValueFromConfigValue(config)))
|
||||
ctx := context.Background()
|
||||
|
||||
diags := b.Configure(populateSchema(t, b.ConfigSchema(ctx), hcl2shim.HCL2ValueFromConfigValue(config)))
|
||||
|
||||
if testCase.expectedErr != "" {
|
||||
if diags.Err() != nil {
|
||||
@ -971,7 +983,9 @@ func TestBackendSSECustomerKeyEnvVar(t *testing.T) {
|
||||
})
|
||||
|
||||
b := New().(*Backend)
|
||||
diags := b.Configure(populateSchema(t, b.ConfigSchema(), hcl2shim.HCL2ValueFromConfigValue(config)))
|
||||
ctx := context.Background()
|
||||
|
||||
diags := b.Configure(populateSchema(t, b.ConfigSchema(ctx), hcl2shim.HCL2ValueFromConfigValue(config)))
|
||||
|
||||
if testCase.expectedErr != "" {
|
||||
if diags.Err() != nil {
|
||||
|
@ -106,7 +106,7 @@ func New(services *disco.Disco) *Remote {
|
||||
}
|
||||
|
||||
// ConfigSchema implements backend.Enhanced.
|
||||
func (b *Remote) ConfigSchema() *configschema.Block {
|
||||
func (b *Remote) ConfigSchema(context.Context) *configschema.Block {
|
||||
return &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"hostname": {
|
||||
|
@ -4,6 +4,7 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
@ -36,7 +37,9 @@ func TestBackendConfig(t *testing.T, b Backend, c hcl.Body) Backend {
|
||||
c = hcl.EmptyBody()
|
||||
}
|
||||
|
||||
schema := b.ConfigSchema()
|
||||
ctx := context.Background()
|
||||
|
||||
schema := b.ConfigSchema(ctx)
|
||||
spec := schema.DecoderSpec()
|
||||
obj, decDiags := hcldec.Decode(c, spec, nil)
|
||||
diags = diags.Append(decDiags)
|
||||
|
@ -4,6 +4,7 @@
|
||||
package tf
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
@ -222,7 +223,9 @@ func getBackend(cfg cty.Value) (backend.Backend, cty.Value, tfdiags.Diagnostics)
|
||||
config = cty.ObjectVal(config.AsValueMap())
|
||||
}
|
||||
|
||||
schema := b.ConfigSchema()
|
||||
ctx := context.TODO()
|
||||
|
||||
schema := b.ConfigSchema(ctx)
|
||||
// Try to coerce the provided value into the desired configuration type.
|
||||
configVal, err := schema.CoerceValue(config)
|
||||
if err != nil {
|
||||
|
@ -4,6 +4,7 @@
|
||||
package tf
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"testing"
|
||||
@ -344,7 +345,7 @@ func TestState_validation(t *testing.T) {
|
||||
|
||||
type backendFailsConfigure struct{}
|
||||
|
||||
func (b backendFailsConfigure) ConfigSchema() *configschema.Block {
|
||||
func (b backendFailsConfigure) ConfigSchema(context.Context) *configschema.Block {
|
||||
log.Printf("[TRACE] backendFailsConfigure.ConfigSchema")
|
||||
return &configschema.Block{} // intentionally empty configuration schema
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ func New(services *disco.Disco) *Cloud {
|
||||
}
|
||||
|
||||
// ConfigSchema implements backend.Enhanced.
|
||||
func (b *Cloud) ConfigSchema() *configschema.Block {
|
||||
func (b *Cloud) ConfigSchema(context.Context) *configschema.Block {
|
||||
return &configschema.Block{
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"hostname": {
|
||||
|
@ -773,7 +773,10 @@ func testBackendState(t *testing.T, s *states.State, c int) (*legacy.State, *htt
|
||||
Config: configs.SynthBody("<testBackendState>", map[string]cty.Value{}),
|
||||
}
|
||||
b := backendInit.Backend("http")()
|
||||
configSchema := b.ConfigSchema()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
configSchema := b.ConfigSchema(ctx)
|
||||
hash := backendConfig.Hash(configSchema)
|
||||
|
||||
state := legacy.NewState()
|
||||
|
@ -464,7 +464,7 @@ func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, ext
|
||||
}
|
||||
|
||||
b := bf()
|
||||
backendSchema := b.ConfigSchema()
|
||||
backendSchema := b.ConfigSchema(ctx)
|
||||
backendConfig = root.Backend
|
||||
|
||||
var overrideDiags tfdiags.Diagnostics
|
||||
|
@ -313,7 +313,9 @@ func (m *Meta) BackendForLocalPlan(settings plans.Backend) (backend.Enhanced, tf
|
||||
b := f()
|
||||
log.Printf("[TRACE] Meta.BackendForLocalPlan: instantiated backend of type %T", b)
|
||||
|
||||
schema := b.ConfigSchema()
|
||||
ctx := context.TODO()
|
||||
|
||||
schema := b.ConfigSchema(ctx)
|
||||
configVal, err := settings.Config.Decode(schema.ImpliedType())
|
||||
if err != nil {
|
||||
diags = diags.Append(fmt.Errorf("saved backend configuration is invalid: %w", err))
|
||||
@ -404,7 +406,9 @@ func (m *Meta) backendCLIOpts() (*backend.CLIOpts, error) {
|
||||
// to modify fields of the operation such as Sequence to specify what will
|
||||
// be called.
|
||||
func (m *Meta) Operation(b backend.Backend, vt arguments.ViewType) *backend.Operation {
|
||||
schema := b.ConfigSchema()
|
||||
ctx := context.TODO()
|
||||
|
||||
schema := b.ConfigSchema(ctx)
|
||||
workspace, err := m.Workspace()
|
||||
if err != nil {
|
||||
// An invalid workspace error would have been raised when creating the
|
||||
@ -493,7 +497,9 @@ func (m *Meta) backendConfig(opts *BackendOpts) (*configs.Backend, int, tfdiags.
|
||||
}
|
||||
b := bf()
|
||||
|
||||
configSchema := b.ConfigSchema()
|
||||
ctx := context.TODO()
|
||||
|
||||
configSchema := b.ConfigSchema(ctx)
|
||||
configBody := c.Config
|
||||
configHash := c.Hash(configSchema)
|
||||
|
||||
@ -812,7 +818,7 @@ func (m *Meta) backendFromState(ctx context.Context) (backend.Backend, tfdiags.D
|
||||
// The configuration saved in the working directory state file is used
|
||||
// in this case, since it will contain any additional values that
|
||||
// were provided via -backend-config arguments on tofu init.
|
||||
schema := b.ConfigSchema()
|
||||
schema := b.ConfigSchema(ctx)
|
||||
configVal, err := s.Backend.Config(schema)
|
||||
if err != nil {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
@ -1057,7 +1063,9 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.Local
|
||||
defer stateLocker.Unlock()
|
||||
}
|
||||
|
||||
configJSON, err := ctyjson.Marshal(configVal, b.ConfigSchema().ImpliedType())
|
||||
ctx := context.TODO()
|
||||
|
||||
configJSON, err := ctyjson.Marshal(configVal, b.ConfigSchema(ctx).ImpliedType())
|
||||
if err != nil {
|
||||
diags = diags.Append(fmt.Errorf("Can't serialize backend configuration as JSON: %w", err))
|
||||
return nil, diags
|
||||
@ -1202,7 +1210,9 @@ func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *clista
|
||||
}
|
||||
}
|
||||
|
||||
configJSON, err := ctyjson.Marshal(configVal, b.ConfigSchema().ImpliedType())
|
||||
ctx := context.TODO()
|
||||
|
||||
configJSON, err := ctyjson.Marshal(configVal, b.ConfigSchema(ctx).ImpliedType())
|
||||
if err != nil {
|
||||
diags = diags.Append(fmt.Errorf("Can't serialize backend configuration as JSON: %w", err))
|
||||
return nil, diags
|
||||
@ -1266,10 +1276,12 @@ func (m *Meta) savedBackend(sMgr *clistate.LocalState) (backend.Backend, tfdiags
|
||||
}
|
||||
b := f()
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
// The configuration saved in the working directory state file is used
|
||||
// in this case, since it will contain any additional values that
|
||||
// were provided via -backend-config arguments on tofu init.
|
||||
schema := b.ConfigSchema()
|
||||
schema := b.ConfigSchema(ctx)
|
||||
configVal, err := s.Backend.Config(schema)
|
||||
if err != nil {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
@ -1354,7 +1366,9 @@ func (m *Meta) backendConfigNeedsMigration(c *configs.Backend, s *legacy.Backend
|
||||
}
|
||||
b := f()
|
||||
|
||||
schema := b.ConfigSchema()
|
||||
ctx := context.TODO()
|
||||
|
||||
schema := b.ConfigSchema(ctx)
|
||||
decSpec := schema.NoneRequired().DecoderSpec()
|
||||
givenVal, diags := hcldec.Decode(c.Config, decSpec, nil)
|
||||
if diags.HasErrors() {
|
||||
@ -1391,7 +1405,9 @@ func (m *Meta) backendInitFromConfig(c *configs.Backend) (backend.Backend, cty.V
|
||||
}
|
||||
b := f()
|
||||
|
||||
schema := b.ConfigSchema()
|
||||
ctx := context.TODO()
|
||||
|
||||
schema := b.ConfigSchema(ctx)
|
||||
decSpec := schema.NoneRequired().DecoderSpec()
|
||||
configVal, hclDiags := hcldec.Decode(c.Config, decSpec, nil)
|
||||
diags = diags.Append(hclDiags)
|
||||
|
@ -478,7 +478,7 @@ func TestPlan_outBackend(t *testing.T) {
|
||||
}
|
||||
{
|
||||
httpBackend := backendinit.Backend("http")()
|
||||
schema := httpBackend.ConfigSchema()
|
||||
schema := httpBackend.ConfigSchema(context.Background())
|
||||
got, err := plan.Backend.Config.Decode(schema.ImpliedType())
|
||||
if err != nil {
|
||||
t.Fatalf("failed to decode backend config in plan: %s", err)
|
||||
|
@ -48,7 +48,7 @@ func FromContextBackendConfig(ctx context.Context) *ResourceData {
|
||||
return ctx.Value(backendConfigKey).(*ResourceData)
|
||||
}
|
||||
|
||||
func (b *Backend) ConfigSchema() *configschema.Block {
|
||||
func (b *Backend) ConfigSchema(context.Context) *configschema.Block {
|
||||
// This is an alias of CoreConfigSchema just to implement the
|
||||
// backend.Backend interface.
|
||||
return b.CoreConfigSchema()
|
||||
|
Loading…
Reference in New Issue
Block a user