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,
}
apply.Run(args)
if p.PrepareProviderConfigCalled {
t.Fatal("Prepare provider config should not be called with a plan")
}
}
func TestApply_refresh(t *testing.T) {

View File

@ -14,8 +14,10 @@ type Interface interface {
// GetSchema returns the complete schema for the provider.
GetSchema() GetSchemaResponse
// PrepareProviderConfig allows the provider to validate the configuration
// values, and set or override any values with defaults.
// PrepareProviderConfig allows the provider to validate the configuration.
// 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
// ValidateResourceTypeConfig allows the provider to validate the resource
@ -99,7 +101,7 @@ type PrepareProviderConfigRequest struct {
}
type PrepareProviderConfigResponse struct {
// PreparedConfig is the configuration as prepared by the provider.
// PreparedConfig is unused.
PreparedConfig cty.Value
// Diagnostics contains any warnings or errors from the method call.
Diagnostics tfdiags.Diagnostics

View File

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

View File

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/tfdiags"
"github.com/zclconf/go-cty/cty"
)
// NodeApplyableProvider represents a provider during an apply.
@ -108,8 +109,29 @@ func (n *NodeApplyableProvider) ConfigureProvider(ctx EvalContext, provider prov
return diags
}
configDiags := ctx.ConfigureProvider(n.Addr, configVal)
configDiags = configDiags.InConfigBody(configBody)
// Allow the provider to validate and insert any defaults into the full
// 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 {
return p.PrepareProviderConfigFn(r)
}
p.PrepareProviderConfigResponse.PreparedConfig = r.Config
return p.PrepareProviderConfigResponse
}