From c5ab496e9fcfec18d482cb6be4869929a88071d3 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 10 Aug 2021 11:30:31 -0400 Subject: [PATCH 1/3] tfsdk: Return warning diagnostic when using `Attribute` or `Schema` type `DeprecationMessage` field Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/71 --- .changelog/pending.txt | 3 +++ tfsdk/attribute.go | 9 +++++++++ tfsdk/attribute_test.go | 33 +++++++++++++++++++++++++++++++++ tfsdk/schema.go | 8 ++++++++ tfsdk/schema_test.go | 37 +++++++++++++++++++++++++++++++++++++ tfsdk/serve_test.go | 14 ++++++++++++++ 6 files changed, 104 insertions(+) create mode 100644 .changelog/pending.txt diff --git a/.changelog/pending.txt b/.changelog/pending.txt new file mode 100644 index 000000000..cd75a272d --- /dev/null +++ b/.changelog/pending.txt @@ -0,0 +1,3 @@ +```release-note:bug +tfsdk: Return warning diagnostic when using `Attribute` or `Schema` type `DeprecationMessage` field +``` diff --git a/tfsdk/attribute.go b/tfsdk/attribute.go index ce0e25f35..605bfc01a 100644 --- a/tfsdk/attribute.go +++ b/tfsdk/attribute.go @@ -344,4 +344,13 @@ func (a Attribute) validate(ctx context.Context, req ValidateAttributeRequest, r return } } + + if a.DeprecationMessage != "" { + resp.Diagnostics = append(resp.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityWarning, + Summary: "Attribute Deprecated", + Detail: a.DeprecationMessage, + Attribute: req.AttributePath, + }) + } } diff --git a/tfsdk/attribute_test.go b/tfsdk/attribute_test.go index 75e9c88ad..229e7681a 100644 --- a/tfsdk/attribute_test.go +++ b/tfsdk/attribute_test.go @@ -803,6 +803,39 @@ func TestAttributeValidate(t *testing.T) { }, resp: ValidateAttributeResponse{}, }, + "deprecation-message": { + req: ValidateAttributeRequest{ + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + Config: Config{ + Raw: tftypes.NewValue(tftypes.Object{ + AttributeTypes: map[string]tftypes.Type{ + "test": tftypes.String, + }, + }, map[string]tftypes.Value{ + "test": tftypes.NewValue(tftypes.String, "testvalue"), + }), + Schema: Schema{ + Attributes: map[string]Attribute{ + "test": { + Type: types.StringType, + Required: true, + DeprecationMessage: "Use something else instead.", + }, + }, + }, + }, + }, + resp: ValidateAttributeResponse{ + Diagnostics: []*tfprotov6.Diagnostic{ + { + Severity: tfprotov6.DiagnosticSeverityWarning, + Summary: "Attribute Deprecated", + Detail: "Use something else instead.", + Attribute: tftypes.NewAttributePath().WithAttributeName("test"), + }, + }, + }, + }, "warnings": { req: ValidateAttributeRequest{ AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), diff --git a/tfsdk/schema.go b/tfsdk/schema.go index cef316126..bff76a332 100644 --- a/tfsdk/schema.go +++ b/tfsdk/schema.go @@ -199,4 +199,12 @@ func (s Schema) validate(ctx context.Context, req ValidateSchemaRequest, resp *V resp.Diagnostics = attributeResp.Diagnostics } + + if s.DeprecationMessage != "" { + resp.Diagnostics = append(resp.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityWarning, + Summary: "Deprecated", + Detail: s.DeprecationMessage, + }) + } } diff --git a/tfsdk/schema_test.go b/tfsdk/schema_test.go index ecb14610a..cb877df49 100644 --- a/tfsdk/schema_test.go +++ b/tfsdk/schema_test.go @@ -556,6 +556,43 @@ func TestSchemaValidate(t *testing.T) { }, resp: ValidateSchemaResponse{}, }, + "deprecation-message": { + req: ValidateSchemaRequest{ + Config: Config{ + Raw: tftypes.NewValue(tftypes.Object{ + AttributeTypes: map[string]tftypes.Type{ + "attr1": tftypes.String, + "attr2": tftypes.String, + }, + }, map[string]tftypes.Value{ + "attr1": tftypes.NewValue(tftypes.String, "attr1value"), + "attr2": tftypes.NewValue(tftypes.String, "attr2value"), + }), + Schema: Schema{ + Attributes: map[string]Attribute{ + "attr1": { + Type: types.StringType, + Required: true, + }, + "attr2": { + Type: types.StringType, + Required: true, + }, + }, + DeprecationMessage: "Use something else instead.", + }, + }, + }, + resp: ValidateSchemaResponse{ + Diagnostics: []*tfprotov6.Diagnostic{ + { + Severity: tfprotov6.DiagnosticSeverityWarning, + Summary: "Deprecated", + Detail: "Use something else instead.", + }, + }, + }, + }, "warnings": { req: ValidateSchemaRequest{ Config: Config{ diff --git a/tfsdk/serve_test.go b/tfsdk/serve_test.go index 836d90fc6..e449ca59f 100644 --- a/tfsdk/serve_test.go +++ b/tfsdk/serve_test.go @@ -413,6 +413,20 @@ func TestServerValidateProviderConfig(t *testing.T) { }), provider: &testServeProvider{}, providerType: testServeProviderProviderType, + + expectedDiags: []*tfprotov6.Diagnostic{ + { + Severity: tfprotov6.DiagnosticSeverityWarning, + Summary: "Attribute Deprecated", + Detail: `Deprecated, please use "optional" instead`, + Attribute: tftypes.NewAttributePath().WithAttributeName("deprecated"), + }, + { + Severity: tfprotov6.DiagnosticSeverityWarning, + Summary: "Deprecated", + Detail: "Deprecated in favor of other_resource", + }, + }, }, "config_validators_no_diags": { config: tftypes.NewValue(testServeResourceTypeConfigValidatorsType, map[string]tftypes.Value{ From 1b51b9ac284960278267aff22742bc84330cbb91 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 10 Aug 2021 12:35:56 -0400 Subject: [PATCH 2/3] Update CHANGELOG for #93 --- .changelog/{pending.txt => 93.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changelog/{pending.txt => 93.txt} (100%) diff --git a/.changelog/pending.txt b/.changelog/93.txt similarity index 100% rename from .changelog/pending.txt rename to .changelog/93.txt From 53ebcc60b825fd110a5696f580a93a633a3deccc Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Mon, 16 Aug 2021 13:15:13 -0400 Subject: [PATCH 3/3] tfsdk: Ensure null values are ignored with deprecations --- tfsdk/attribute.go | 29 +++++++++++++++----- tfsdk/attribute_test.go | 61 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/tfsdk/attribute.go b/tfsdk/attribute.go index 605bfc01a..04a201905 100644 --- a/tfsdk/attribute.go +++ b/tfsdk/attribute.go @@ -345,12 +345,27 @@ func (a Attribute) validate(ctx context.Context, req ValidateAttributeRequest, r } } - if a.DeprecationMessage != "" { - resp.Diagnostics = append(resp.Diagnostics, &tfprotov6.Diagnostic{ - Severity: tfprotov6.DiagnosticSeverityWarning, - Summary: "Attribute Deprecated", - Detail: a.DeprecationMessage, - Attribute: req.AttributePath, - }) + if a.DeprecationMessage != "" && attributeConfig != nil { + tfValue, err := attributeConfig.ToTerraformValue(ctx) + + if err != nil { + resp.Diagnostics = append(resp.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityError, + Summary: "Attribute Validation Error", + Detail: "Attribute validation cannot convert value. Report this to the provider developer:\n\n" + err.Error(), + Attribute: req.AttributePath, + }) + + return + } + + if tfValue != nil { + resp.Diagnostics = append(resp.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityWarning, + Summary: "Attribute Deprecated", + Detail: a.DeprecationMessage, + Attribute: req.AttributePath, + }) + } } } diff --git a/tfsdk/attribute_test.go b/tfsdk/attribute_test.go index 229e7681a..08ae6e41b 100644 --- a/tfsdk/attribute_test.go +++ b/tfsdk/attribute_test.go @@ -803,7 +803,7 @@ func TestAttributeValidate(t *testing.T) { }, resp: ValidateAttributeResponse{}, }, - "deprecation-message": { + "deprecation-message-known": { req: ValidateAttributeRequest{ AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), Config: Config{ @@ -818,7 +818,64 @@ func TestAttributeValidate(t *testing.T) { Attributes: map[string]Attribute{ "test": { Type: types.StringType, - Required: true, + Optional: true, + DeprecationMessage: "Use something else instead.", + }, + }, + }, + }, + }, + resp: ValidateAttributeResponse{ + Diagnostics: []*tfprotov6.Diagnostic{ + { + Severity: tfprotov6.DiagnosticSeverityWarning, + Summary: "Attribute Deprecated", + Detail: "Use something else instead.", + Attribute: tftypes.NewAttributePath().WithAttributeName("test"), + }, + }, + }, + }, + "deprecation-message-null": { + req: ValidateAttributeRequest{ + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + Config: Config{ + Raw: tftypes.NewValue(tftypes.Object{ + AttributeTypes: map[string]tftypes.Type{ + "test": tftypes.String, + }, + }, map[string]tftypes.Value{ + "test": tftypes.NewValue(tftypes.String, nil), + }), + Schema: Schema{ + Attributes: map[string]Attribute{ + "test": { + Type: types.StringType, + Optional: true, + DeprecationMessage: "Use something else instead.", + }, + }, + }, + }, + }, + resp: ValidateAttributeResponse{}, + }, + "deprecation-message-unknown": { + req: ValidateAttributeRequest{ + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + Config: Config{ + Raw: tftypes.NewValue(tftypes.Object{ + AttributeTypes: map[string]tftypes.Type{ + "test": tftypes.String, + }, + }, map[string]tftypes.Value{ + "test": tftypes.NewValue(tftypes.String, tftypes.UnknownValue), + }), + Schema: Schema{ + Attributes: map[string]Attribute{ + "test": { + Type: types.StringType, + Optional: true, DeprecationMessage: "Use something else instead.", }, },