Flow allowUnknows
for Diff/Check Config
We pass this information for Diff and Check on specific resources, so we can correctly block unknows from flowing to plugins during applies.
This commit is contained in:
parent
e574f33fa0
commit
f897bf8b4b
|
@ -715,7 +715,8 @@ func TestSingleResourceDefaultProviderReplace(t *testing.T) {
|
||||||
loaders := []*deploytest.ProviderLoader{
|
loaders := []*deploytest.ProviderLoader{
|
||||||
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||||
return &deploytest.Provider{
|
return &deploytest.Provider{
|
||||||
DiffConfigF: func(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
DiffConfigF: func(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
// Always require replacement.
|
// Always require replacement.
|
||||||
keys := []resource.PropertyKey{}
|
keys := []resource.PropertyKey{}
|
||||||
for k := range news {
|
for k := range news {
|
||||||
|
@ -793,7 +794,8 @@ func TestSingleResourceExplicitProviderReplace(t *testing.T) {
|
||||||
loaders := []*deploytest.ProviderLoader{
|
loaders := []*deploytest.ProviderLoader{
|
||||||
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||||
return &deploytest.Provider{
|
return &deploytest.Provider{
|
||||||
DiffConfigF: func(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
DiffConfigF: func(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
// Always require replacement.
|
// Always require replacement.
|
||||||
keys := []resource.PropertyKey{}
|
keys := []resource.PropertyKey{}
|
||||||
for k := range news {
|
for k := range news {
|
||||||
|
@ -882,7 +884,8 @@ func TestSingleResourceExplicitProviderDeleteBeforeReplace(t *testing.T) {
|
||||||
loaders := []*deploytest.ProviderLoader{
|
loaders := []*deploytest.ProviderLoader{
|
||||||
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||||
return &deploytest.Provider{
|
return &deploytest.Provider{
|
||||||
DiffConfigF: func(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
DiffConfigF: func(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
// Always require replacement.
|
// Always require replacement.
|
||||||
keys := []resource.PropertyKey{}
|
keys := []resource.PropertyKey{}
|
||||||
for k := range news {
|
for k := range news {
|
||||||
|
@ -2598,7 +2601,8 @@ func TestDeleteBeforeReplace(t *testing.T) {
|
||||||
loaders := []*deploytest.ProviderLoader{
|
loaders := []*deploytest.ProviderLoader{
|
||||||
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||||
return &deploytest.Provider{
|
return &deploytest.Provider{
|
||||||
DiffConfigF: func(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
DiffConfigF: func(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
if !olds["A"].DeepEquals(news["A"]) {
|
if !olds["A"].DeepEquals(news["A"]) {
|
||||||
return plugin.DiffResult{
|
return plugin.DiffResult{
|
||||||
ReplaceKeys: []resource.PropertyKey{"A"},
|
ReplaceKeys: []resource.PropertyKey{"A"},
|
||||||
|
|
|
@ -39,13 +39,14 @@ func (p *builtinProvider) Pkg() tokens.Package {
|
||||||
|
|
||||||
// CheckConfig validates the configuration for this resource provider.
|
// CheckConfig validates the configuration for this resource provider.
|
||||||
func (p *builtinProvider) CheckConfig(urn resource.URN, olds,
|
func (p *builtinProvider) CheckConfig(urn resource.URN, olds,
|
||||||
news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
||||||
|
|
||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DiffConfig checks what impacts a hypothetical change to this provider's configuration will have on the provider.
|
// DiffConfig checks what impacts a hypothetical change to this provider's configuration will have on the provider.
|
||||||
func (p *builtinProvider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
func (p *builtinProvider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
return plugin.DiffResult{Changes: plugin.DiffNone}, nil
|
return plugin.DiffResult{Changes: plugin.DiffNone}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ type Provider struct {
|
||||||
configured bool
|
configured bool
|
||||||
|
|
||||||
CheckConfigF func(urn resource.URN, olds,
|
CheckConfigF func(urn resource.URN, olds,
|
||||||
news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error)
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error)
|
||||||
DiffConfigF func(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error)
|
DiffConfigF func(urn resource.URN, olds, news resource.PropertyMap, allowUnknowns bool) (plugin.DiffResult, error)
|
||||||
ConfigureF func(news resource.PropertyMap) error
|
ConfigureF func(news resource.PropertyMap) error
|
||||||
|
|
||||||
CheckF func(urn resource.URN,
|
CheckF func(urn resource.URN,
|
||||||
|
@ -77,17 +77,18 @@ func (prov *Provider) GetPluginInfo() (workspace.PluginInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (prov *Provider) CheckConfig(urn resource.URN, olds,
|
func (prov *Provider) CheckConfig(urn resource.URN, olds,
|
||||||
news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
||||||
if prov.CheckConfigF == nil {
|
if prov.CheckConfigF == nil {
|
||||||
return news, nil, nil
|
return news, nil, nil
|
||||||
}
|
}
|
||||||
return prov.CheckConfigF(urn, olds, news)
|
return prov.CheckConfigF(urn, olds, news, allowUnknowns)
|
||||||
}
|
}
|
||||||
func (prov *Provider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
func (prov *Provider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
if prov.DiffConfigF == nil {
|
if prov.DiffConfigF == nil {
|
||||||
return plugin.DiffResult{}, nil
|
return plugin.DiffResult{}, nil
|
||||||
}
|
}
|
||||||
return prov.DiffConfigF(urn, olds, news)
|
return prov.DiffConfigF(urn, olds, news, allowUnknowns)
|
||||||
}
|
}
|
||||||
func (prov *Provider) Configure(inputs resource.PropertyMap) error {
|
func (prov *Provider) Configure(inputs resource.PropertyMap) error {
|
||||||
contract.Assert(!prov.configured)
|
contract.Assert(!prov.configured)
|
||||||
|
|
|
@ -186,14 +186,15 @@ func (r *Registry) label() string {
|
||||||
|
|
||||||
// CheckConfig validates the configuration for this resource provider.
|
// CheckConfig validates the configuration for this resource provider.
|
||||||
func (r *Registry) CheckConfig(urn resource.URN, olds,
|
func (r *Registry) CheckConfig(urn resource.URN, olds,
|
||||||
news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
||||||
|
|
||||||
contract.Fail()
|
contract.Fail()
|
||||||
return nil, nil, errors.New("the provider registry is not configurable")
|
return nil, nil, errors.New("the provider registry is not configurable")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DiffConfig checks what impacts a hypothetical change to this provider's configuration will have on the provider.
|
// DiffConfig checks what impacts a hypothetical change to this provider's configuration will have on the provider.
|
||||||
func (r *Registry) DiffConfig(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
func (r *Registry) DiffConfig(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
contract.Fail()
|
contract.Fail()
|
||||||
return plugin.DiffResult{}, errors.New("the provider registry is not configurable")
|
return plugin.DiffResult{}, errors.New("the provider registry is not configurable")
|
||||||
}
|
}
|
||||||
|
@ -233,7 +234,7 @@ func (r *Registry) Check(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the provider's config. If the check fails, unload the provider.
|
// Check the provider's config. If the check fails, unload the provider.
|
||||||
inputs, failures, err := provider.CheckConfig(urn, olds, news)
|
inputs, failures, err := provider.CheckConfig(urn, olds, news, allowUnknowns)
|
||||||
if len(failures) != 0 || err != nil {
|
if len(failures) != 0 || err != nil {
|
||||||
closeErr := r.host.CloseProvider(provider)
|
closeErr := r.host.CloseProvider(provider)
|
||||||
contract.IgnoreError(closeErr)
|
contract.IgnoreError(closeErr)
|
||||||
|
@ -276,7 +277,7 @@ func (r *Registry) Diff(urn resource.URN, id resource.ID, olds, news resource.Pr
|
||||||
provider, ok = r.GetProvider(mustNewReference(urn, id))
|
provider, ok = r.GetProvider(mustNewReference(urn, id))
|
||||||
contract.Assertf(ok, "Provider must have been registered by NewRegistry for DBR Diff (%v::%v)", urn, id)
|
contract.Assertf(ok, "Provider must have been registered by NewRegistry for DBR Diff (%v::%v)", urn, id)
|
||||||
|
|
||||||
diff, err := provider.DiffConfig(urn, olds, news)
|
diff, err := provider.DiffConfig(urn, olds, news, allowUnknowns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return plugin.DiffResult{Changes: plugin.DiffUnknown}, err
|
return plugin.DiffResult{Changes: plugin.DiffUnknown}, err
|
||||||
}
|
}
|
||||||
|
@ -284,7 +285,7 @@ func (r *Registry) Diff(urn resource.URN, id resource.ID, olds, news resource.Pr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diff the properties.
|
// Diff the properties.
|
||||||
diff, err := provider.DiffConfig(urn, olds, news)
|
diff, err := provider.DiffConfig(urn, olds, news, allowUnknowns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return plugin.DiffResult{Changes: plugin.DiffUnknown}, err
|
return plugin.DiffResult{Changes: plugin.DiffUnknown}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,8 @@ type testProvider struct {
|
||||||
version semver.Version
|
version semver.Version
|
||||||
configured bool
|
configured bool
|
||||||
checkConfig func(resource.URN, resource.PropertyMap,
|
checkConfig func(resource.URN, resource.PropertyMap,
|
||||||
resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error)
|
resource.PropertyMap, bool) (resource.PropertyMap, []plugin.CheckFailure, error)
|
||||||
diffConfig func(resource.URN, resource.PropertyMap, resource.PropertyMap) (plugin.DiffResult, error)
|
diffConfig func(resource.URN, resource.PropertyMap, resource.PropertyMap, bool) (plugin.DiffResult, error)
|
||||||
config func(resource.PropertyMap) error
|
config func(resource.PropertyMap) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,11 +93,12 @@ func (prov *testProvider) Pkg() tokens.Package {
|
||||||
return prov.pkg
|
return prov.pkg
|
||||||
}
|
}
|
||||||
func (prov *testProvider) CheckConfig(urn resource.URN, olds,
|
func (prov *testProvider) CheckConfig(urn resource.URN, olds,
|
||||||
news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
||||||
return prov.checkConfig(urn, olds, news)
|
return prov.checkConfig(urn, olds, news, allowUnknowns)
|
||||||
}
|
}
|
||||||
func (prov *testProvider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
func (prov *testProvider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
return prov.diffConfig(urn, olds, news)
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
|
return prov.diffConfig(urn, olds, news, allowUnknowns)
|
||||||
}
|
}
|
||||||
func (prov *testProvider) Configure(inputs resource.PropertyMap) error {
|
func (prov *testProvider) Configure(inputs resource.PropertyMap) error {
|
||||||
if err := prov.config(inputs); err != nil {
|
if err := prov.config(inputs); err != nil {
|
||||||
|
@ -204,10 +205,11 @@ func newSimpleLoader(t *testing.T, pkg, version string, config func(resource.Pro
|
||||||
pkg: pkg,
|
pkg: pkg,
|
||||||
version: ver,
|
version: ver,
|
||||||
checkConfig: func(urn resource.URN, olds,
|
checkConfig: func(urn resource.URN, olds,
|
||||||
news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
||||||
return news, nil, nil
|
return news, nil, nil
|
||||||
},
|
},
|
||||||
diffConfig: func(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
diffConfig: func(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
return plugin.DiffResult{}, nil
|
return plugin.DiffResult{}, nil
|
||||||
},
|
},
|
||||||
config: config,
|
config: config,
|
||||||
|
@ -515,10 +517,11 @@ func TestCRUDPreview(t *testing.T) {
|
||||||
pkg: pkg,
|
pkg: pkg,
|
||||||
version: ver,
|
version: ver,
|
||||||
checkConfig: func(urn resource.URN, olds,
|
checkConfig: func(urn resource.URN, olds,
|
||||||
news resource.PropertyMap) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []plugin.CheckFailure, error) {
|
||||||
return news, nil, nil
|
return news, nil, nil
|
||||||
},
|
},
|
||||||
diffConfig: func(urn resource.URN, olds, news resource.PropertyMap) (plugin.DiffResult, error) {
|
diffConfig: func(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (plugin.DiffResult, error) {
|
||||||
// Always reuquire replacement.
|
// Always reuquire replacement.
|
||||||
return plugin.DiffResult{ReplaceKeys: []resource.PropertyKey{"id"}}, nil
|
return plugin.DiffResult{ReplaceKeys: []resource.PropertyKey{"id"}}, nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,9 +39,10 @@ type Provider interface {
|
||||||
Pkg() tokens.Package
|
Pkg() tokens.Package
|
||||||
|
|
||||||
// CheckConfig validates the configuration for this resource provider.
|
// CheckConfig validates the configuration for this resource provider.
|
||||||
CheckConfig(urn resource.URN, olds, news resource.PropertyMap) (resource.PropertyMap, []CheckFailure, error)
|
CheckConfig(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (resource.PropertyMap, []CheckFailure, error)
|
||||||
// DiffConfig checks what impacts a hypothetical change to this provider's configuration will have on the provider.
|
// DiffConfig checks what impacts a hypothetical change to this provider's configuration will have on the provider.
|
||||||
DiffConfig(urn resource.URN, olds, news resource.PropertyMap) (DiffResult, error)
|
DiffConfig(urn resource.URN, olds, news resource.PropertyMap, allowUnknowns bool) (DiffResult, error)
|
||||||
// Configure configures the resource provider with "globals" that control its behavior.
|
// Configure configures the resource provider with "globals" that control its behavior.
|
||||||
Configure(inputs resource.PropertyMap) error
|
Configure(inputs resource.PropertyMap) error
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ func (p *provider) label() string {
|
||||||
|
|
||||||
// CheckConfig validates the configuration for this resource provider.
|
// CheckConfig validates the configuration for this resource provider.
|
||||||
func (p *provider) CheckConfig(urn resource.URN, olds,
|
func (p *provider) CheckConfig(urn resource.URN, olds,
|
||||||
news resource.PropertyMap) (resource.PropertyMap, []CheckFailure, error) {
|
news resource.PropertyMap, allowUnknowns bool) (resource.PropertyMap, []CheckFailure, error) {
|
||||||
// Ensure that all config values are strings or unknowns.
|
// Ensure that all config values are strings or unknowns.
|
||||||
var failures []CheckFailure
|
var failures []CheckFailure
|
||||||
for k, v := range news {
|
for k, v := range news {
|
||||||
|
@ -112,7 +112,8 @@ func (p *provider) CheckConfig(urn resource.URN, olds,
|
||||||
}
|
}
|
||||||
|
|
||||||
// DiffConfig checks what impacts a hypothetical change to this provider's configuration will have on the provider.
|
// DiffConfig checks what impacts a hypothetical change to this provider's configuration will have on the provider.
|
||||||
func (p *provider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap) (DiffResult, error) {
|
func (p *provider) DiffConfig(urn resource.URN, olds, news resource.PropertyMap,
|
||||||
|
allowUnknowns bool) (DiffResult, error) {
|
||||||
// There are two interesting scenarios with the present gRPC interface:
|
// There are two interesting scenarios with the present gRPC interface:
|
||||||
// 1. Configuration differences in which all properties are known
|
// 1. Configuration differences in which all properties are known
|
||||||
// 2. Configuration differences in which some new property is unknown.
|
// 2. Configuration differences in which some new property is unknown.
|
||||||
|
|
Loading…
Reference in a new issue