diff --git a/terraform/context_components_test.go b/terraform/context_components_test.go index 28feebdc3..fd2ac074b 100644 --- a/terraform/context_components_test.go +++ b/terraform/context_components_test.go @@ -62,7 +62,7 @@ func simpleTestSchema() *configschema.Block { Optional: true, }, "test_number": { - Type: cty.String, + Type: cty.Number, Optional: true, }, "test_bool": { diff --git a/terraform/eval_validate.go b/terraform/eval_validate.go index 8f1fd7e08..38ea7086f 100644 --- a/terraform/eval_validate.go +++ b/terraform/eval_validate.go @@ -374,9 +374,11 @@ func (n *EvalValidateResource) Validate(ctx EvalContext) tfdiags.Diagnostics { } } + // Use unmarked value for validate request + unmarkedConfigVal, _ := configVal.UnmarkDeep() req := providers.ValidateResourceTypeConfigRequest{ TypeName: cfg.Type, - Config: configVal, + Config: unmarkedConfigVal, } resp := provider.ValidateResourceTypeConfig(req) @@ -404,9 +406,11 @@ func (n *EvalValidateResource) Validate(ctx EvalContext) tfdiags.Diagnostics { return diags } + // Use unmarked value for validate request + unmarkedConfigVal, _ := configVal.UnmarkDeep() req := providers.ValidateDataSourceConfigRequest{ TypeName: cfg.Type, - Config: configVal, + Config: unmarkedConfigVal, } resp := provider.ValidateDataSourceConfig(req) diff --git a/terraform/eval_validate_test.go b/terraform/eval_validate_test.go index 5ff84fee1..4d23704e6 100644 --- a/terraform/eval_validate_test.go +++ b/terraform/eval_validate_test.go @@ -26,6 +26,9 @@ func TestEvalValidateResource_managedResource(t *testing.T) { 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) } + 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{} } @@ -36,6 +39,7 @@ func TestEvalValidateResource_managedResource(t *testing.T) { Name: "foo", Config: configs.SynthBody("", map[string]cty.Value{ "test_string": cty.StringVal("bar"), + "test_number": cty.NumberIntVal(2).Mark("sensitive"), }), } 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) { 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{} } @@ -127,6 +134,7 @@ func TestEvalValidateResource_dataSource(t *testing.T) { Name: "foo", Config: configs.SynthBody("", map[string]cty.Value{ "test_string": cty.StringVal("bar"), + "test_number": cty.NumberIntVal(2).Mark("sensitive"), }), } diff --git a/terraform/provider_mock.go b/terraform/provider_mock.go index 2a6f6dbf0..53c46d994 100644 --- a/terraform/provider_mock.go +++ b/terraform/provider_mock.go @@ -6,6 +6,7 @@ import ( "github.com/zclconf/go-cty/cty" 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/providers" @@ -124,6 +125,24 @@ func (p *MockProvider) getSchema() providers.GetSchemaResponse { 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 { p.Lock() defer p.Unlock() @@ -137,13 +156,22 @@ func (p *MockProvider) PrepareProviderConfig(r providers.PrepareProviderConfigRe return p.PrepareProviderConfigResponse } -func (p *MockProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTypeConfigRequest) providers.ValidateResourceTypeConfigResponse { +func (p *MockProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTypeConfigRequest) (resp providers.ValidateResourceTypeConfigResponse) { p.Lock() defer p.Unlock() p.ValidateResourceTypeConfigCalled = true 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 { return p.ValidateResourceTypeConfigFn(r) } @@ -151,13 +179,21 @@ func (p *MockProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTy return p.ValidateResourceTypeConfigResponse } -func (p *MockProvider) ValidateDataSourceConfig(r providers.ValidateDataSourceConfigRequest) providers.ValidateDataSourceConfigResponse { +func (p *MockProvider) ValidateDataSourceConfig(r providers.ValidateDataSourceConfigRequest) (resp providers.ValidateDataSourceConfigResponse) { p.Lock() defer p.Unlock() p.ValidateDataSourceConfigCalled = true 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 { return p.ValidateDataSourceConfigFn(r) }