Merge pull request #26816 from hashicorp/jbardin/provider-config

Validate final provider configuration
This commit is contained in:
James Bardin 2020-11-04 16:57:02 -05:00 committed by GitHub
commit c5b4ccfe8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 9 deletions

View File

@ -798,9 +798,6 @@ func TestApply_planNoModuleFiles(t *testing.T) {
planPath, planPath,
} }
apply.Run(args) apply.Run(args)
if p.PrepareProviderConfigCalled {
t.Fatal("Prepare provider config should not be called with a plan")
}
} }
func TestApply_refresh(t *testing.T) { func TestApply_refresh(t *testing.T) {

View File

@ -14,8 +14,10 @@ type Interface interface {
// GetSchema returns the complete schema for the provider. // GetSchema returns the complete schema for the provider.
GetSchema() GetSchemaResponse GetSchema() GetSchemaResponse
// PrepareProviderConfig allows the provider to validate the configuration // PrepareProviderConfig allows the provider to validate the configuration.
// values, and set or override any values with defaults. // The PrepareProviderConfigResponse.PreparedConfig field is unused. The
// final configuration is not stored in the state, and any modifications
// that need to be made must be made during the Configure method call.
PrepareProviderConfig(PrepareProviderConfigRequest) PrepareProviderConfigResponse PrepareProviderConfig(PrepareProviderConfigRequest) PrepareProviderConfigResponse
// ValidateResourceTypeConfig allows the provider to validate the resource // ValidateResourceTypeConfig allows the provider to validate the resource
@ -99,7 +101,7 @@ type PrepareProviderConfigRequest struct {
} }
type PrepareProviderConfigResponse struct { type PrepareProviderConfigResponse struct {
// PreparedConfig is the configuration as prepared by the provider. // PreparedConfig is unused.
PreparedConfig cty.Value PreparedConfig cty.Value
// Diagnostics contains any warnings or errors from the method call. // Diagnostics contains any warnings or errors from the method call.
Diagnostics tfdiags.Diagnostics Diagnostics tfdiags.Diagnostics

View File

@ -78,6 +78,11 @@ func TestContext2Plan_basic(t *testing.T) {
t.Fatal("unknown instance:", i) t.Fatal("unknown instance:", i)
} }
} }
if !p.PrepareProviderConfigCalled {
t.Fatal("provider config was not checked before Configure")
}
} }
func TestContext2Plan_createBefore_deposed(t *testing.T) { func TestContext2Plan_createBefore_deposed(t *testing.T) {

View File

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform/configs/configschema" "github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/tfdiags" "github.com/hashicorp/terraform/tfdiags"
"github.com/zclconf/go-cty/cty"
) )
// NodeApplyableProvider represents a provider during an apply. // NodeApplyableProvider represents a provider during an apply.
@ -108,8 +109,29 @@ func (n *NodeApplyableProvider) ConfigureProvider(ctx EvalContext, provider prov
return diags return diags
} }
configDiags := ctx.ConfigureProvider(n.Addr, configVal) // Allow the provider to validate and insert any defaults into the full
configDiags = configDiags.InConfigBody(configBody) // configuration.
req := providers.PrepareProviderConfigRequest{
Config: configVal,
}
return configDiags // PrepareProviderConfig is only used for validation. We are intentionally
// ignoring the PreparedConfig field to maintain existing behavior.
prepareResp := provider.PrepareProviderConfig(req)
diags = diags.Append(prepareResp.Diagnostics)
if diags.HasErrors() {
return diags
}
// If the provider returns something different, log a warning to help
// indicate to provider developers that the value is not used.
preparedCfg := prepareResp.PreparedConfig
if preparedCfg != cty.NilVal && !preparedCfg.IsNull() && !preparedCfg.RawEquals(configVal) {
log.Printf("[WARN] PrepareProviderConfig from %q changed the config value, but that value is unused", n.Addr)
}
configDiags := ctx.ConfigureProvider(n.Addr, configVal)
diags = diags.Append(configDiags.InConfigBody(configBody))
return diags
} }

View File

@ -133,6 +133,7 @@ func (p *MockProvider) PrepareProviderConfig(r providers.PrepareProviderConfigRe
if p.PrepareProviderConfigFn != nil { if p.PrepareProviderConfigFn != nil {
return p.PrepareProviderConfigFn(r) return p.PrepareProviderConfigFn(r)
} }
p.PrepareProviderConfigResponse.PreparedConfig = r.Config
return p.PrepareProviderConfigResponse return p.PrepareProviderConfigResponse
} }