Unmark values before provider validate call

Unmark values before calling provider's validate
function, this was not tested as the mock
provider does not use Marshall. Update mock
provider funcs to marshall and error if there
was an error in marshalling
This commit is contained in:
Pam Selle 2020-11-19 17:24:55 -05:00
parent b8d448de83
commit 578a3d89d1
4 changed files with 53 additions and 5 deletions

View File

@ -62,7 +62,7 @@ func simpleTestSchema() *configschema.Block {
Optional: true, Optional: true,
}, },
"test_number": { "test_number": {
Type: cty.String, Type: cty.Number,
Optional: true, Optional: true,
}, },
"test_bool": { "test_bool": {

View File

@ -374,9 +374,11 @@ func (n *EvalValidateResource) Validate(ctx EvalContext) tfdiags.Diagnostics {
} }
} }
// Use unmarked value for validate request
unmarkedConfigVal, _ := configVal.UnmarkDeep()
req := providers.ValidateResourceTypeConfigRequest{ req := providers.ValidateResourceTypeConfigRequest{
TypeName: cfg.Type, TypeName: cfg.Type,
Config: configVal, Config: unmarkedConfigVal,
} }
resp := provider.ValidateResourceTypeConfig(req) resp := provider.ValidateResourceTypeConfig(req)
@ -404,9 +406,11 @@ func (n *EvalValidateResource) Validate(ctx EvalContext) tfdiags.Diagnostics {
return diags return diags
} }
// Use unmarked value for validate request
unmarkedConfigVal, _ := configVal.UnmarkDeep()
req := providers.ValidateDataSourceConfigRequest{ req := providers.ValidateDataSourceConfigRequest{
TypeName: cfg.Type, TypeName: cfg.Type,
Config: configVal, Config: unmarkedConfigVal,
} }
resp := provider.ValidateDataSourceConfig(req) resp := provider.ValidateDataSourceConfig(req)

View File

@ -26,6 +26,9 @@ func TestEvalValidateResource_managedResource(t *testing.T) {
if got, want := req.Config.GetAttr("test_string"), cty.StringVal("bar"); !got.RawEquals(want) { if got, want := req.Config.GetAttr("test_string"), cty.StringVal("bar"); !got.RawEquals(want) {
t.Fatalf("wrong value for test_string\ngot: %#v\nwant: %#v", got, want) t.Fatalf("wrong value for test_string\ngot: %#v\nwant: %#v", got, want)
} }
if got, want := req.Config.GetAttr("test_number"), cty.NumberIntVal(2); !got.RawEquals(want) {
t.Fatalf("wrong value for test_number\ngot: %#v\nwant: %#v", got, want)
}
return providers.ValidateResourceTypeConfigResponse{} return providers.ValidateResourceTypeConfigResponse{}
} }
@ -36,6 +39,7 @@ func TestEvalValidateResource_managedResource(t *testing.T) {
Name: "foo", Name: "foo",
Config: configs.SynthBody("", map[string]cty.Value{ Config: configs.SynthBody("", map[string]cty.Value{
"test_string": cty.StringVal("bar"), "test_string": cty.StringVal("bar"),
"test_number": cty.NumberIntVal(2).Mark("sensitive"),
}), }),
} }
node := &EvalValidateResource{ node := &EvalValidateResource{
@ -117,6 +121,9 @@ func TestEvalValidateResource_dataSource(t *testing.T) {
if got, want := req.Config.GetAttr("test_string"), cty.StringVal("bar"); !got.RawEquals(want) { if got, want := req.Config.GetAttr("test_string"), cty.StringVal("bar"); !got.RawEquals(want) {
t.Fatalf("wrong value for test_string\ngot: %#v\nwant: %#v", got, want) t.Fatalf("wrong value for test_string\ngot: %#v\nwant: %#v", got, want)
} }
if got, want := req.Config.GetAttr("test_number"), cty.NumberIntVal(2); !got.RawEquals(want) {
t.Fatalf("wrong value for test_number\ngot: %#v\nwant: %#v", got, want)
}
return providers.ValidateDataSourceConfigResponse{} return providers.ValidateDataSourceConfigResponse{}
} }
@ -127,6 +134,7 @@ func TestEvalValidateResource_dataSource(t *testing.T) {
Name: "foo", Name: "foo",
Config: configs.SynthBody("", map[string]cty.Value{ Config: configs.SynthBody("", map[string]cty.Value{
"test_string": cty.StringVal("bar"), "test_string": cty.StringVal("bar"),
"test_number": cty.NumberIntVal(2).Mark("sensitive"),
}), }),
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
ctyjson "github.com/zclconf/go-cty/cty/json" ctyjson "github.com/zclconf/go-cty/cty/json"
"github.com/zclconf/go-cty/cty/msgpack"
"github.com/hashicorp/terraform/configs/hcl2shim" "github.com/hashicorp/terraform/configs/hcl2shim"
"github.com/hashicorp/terraform/providers" "github.com/hashicorp/terraform/providers"
@ -124,6 +125,24 @@ func (p *MockProvider) getSchema() providers.GetSchemaResponse {
return ret return ret
} }
func (p *MockProvider) getResourceSchema(name string) providers.Schema {
schema := p.getSchema()
resSchema, ok := schema.ResourceTypes[name]
if !ok {
panic("unknown resource type " + name)
}
return resSchema
}
func (p *MockProvider) getDatasourceSchema(name string) providers.Schema {
schema := p.getSchema()
dataSchema, ok := schema.DataSources[name]
if !ok {
panic("unknown data source " + name)
}
return dataSchema
}
func (p *MockProvider) PrepareProviderConfig(r providers.PrepareProviderConfigRequest) providers.PrepareProviderConfigResponse { func (p *MockProvider) PrepareProviderConfig(r providers.PrepareProviderConfigRequest) providers.PrepareProviderConfigResponse {
p.Lock() p.Lock()
defer p.Unlock() defer p.Unlock()
@ -137,13 +156,22 @@ func (p *MockProvider) PrepareProviderConfig(r providers.PrepareProviderConfigRe
return p.PrepareProviderConfigResponse return p.PrepareProviderConfigResponse
} }
func (p *MockProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTypeConfigRequest) providers.ValidateResourceTypeConfigResponse { func (p *MockProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTypeConfigRequest) (resp providers.ValidateResourceTypeConfigResponse) {
p.Lock() p.Lock()
defer p.Unlock() defer p.Unlock()
p.ValidateResourceTypeConfigCalled = true p.ValidateResourceTypeConfigCalled = true
p.ValidateResourceTypeConfigRequest = r p.ValidateResourceTypeConfigRequest = r
// Marshall the value to replicate behavior by the GRPC protocol,
// and return any relevant errors
resourceSchema := p.getResourceSchema(r.TypeName)
_, err := msgpack.Marshal(r.Config, resourceSchema.Block.ImpliedType())
if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(err)
return resp
}
if p.ValidateResourceTypeConfigFn != nil { if p.ValidateResourceTypeConfigFn != nil {
return p.ValidateResourceTypeConfigFn(r) return p.ValidateResourceTypeConfigFn(r)
} }
@ -151,13 +179,21 @@ func (p *MockProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTy
return p.ValidateResourceTypeConfigResponse return p.ValidateResourceTypeConfigResponse
} }
func (p *MockProvider) ValidateDataSourceConfig(r providers.ValidateDataSourceConfigRequest) providers.ValidateDataSourceConfigResponse { func (p *MockProvider) ValidateDataSourceConfig(r providers.ValidateDataSourceConfigRequest) (resp providers.ValidateDataSourceConfigResponse) {
p.Lock() p.Lock()
defer p.Unlock() defer p.Unlock()
p.ValidateDataSourceConfigCalled = true p.ValidateDataSourceConfigCalled = true
p.ValidateDataSourceConfigRequest = r p.ValidateDataSourceConfigRequest = r
// Marshall the value to replicate behavior by the GRPC protocol
dataSchema := p.getDatasourceSchema(r.TypeName)
_, err := msgpack.Marshal(r.Config, dataSchema.Block.ImpliedType())
if err != nil {
resp.Diagnostics = resp.Diagnostics.Append(err)
return resp
}
if p.ValidateDataSourceConfigFn != nil { if p.ValidateDataSourceConfigFn != nil {
return p.ValidateDataSourceConfigFn(r) return p.ValidateDataSourceConfigFn(r)
} }