Make backend.ConfigSchema accept a context (#776)

Signed-off-by: Marcin Wyszynski <marcin.pixie@gmail.com>
This commit is contained in:
Marcin Wyszynski 2023-10-24 13:14:01 +02:00 committed by GitHub
parent a6ebabfea6
commit bda32938e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 79 additions and 33 deletions

View File

@ -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

View File

@ -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{

View File

@ -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{}
}

View File

@ -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)

View File

@ -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": {

View File

@ -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)

View File

@ -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 {

View File

@ -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": {

View File

@ -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)

View File

@ -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 {

View File

@ -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
}

View File

@ -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": {

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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()