-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tfprotov5+tfprotov6: Replace usage of diagnostics in CallFunction RPC…
… with function error (#380) * tfprotov5+tfprotov6: Replace usage of diagnostics in CallFunction RPC with function error Reference: hashicorp/terraform#34603 The next version of the plugin protocol (5.5/6.5) includes support for provider defined functions. This change modifies the response returned from the CallFunction RPC, replacing diagnostics with function error. * Fix protoc version * Add changelog * Removing function argument from diagnostics * Renaming param from msg to text for function errorr * Adding change log
- Loading branch information
1 parent
0624268
commit 90a82fe
Showing
41 changed files
with
3,103 additions
and
2,200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: BREAKING CHANGES | ||
body: 'tfprotov5+tfprotov6: Modified the response returned from the CallFunction RPC, | ||
replacing diagnostics with function error' | ||
time: 2024-02-21T10:30:10.223878Z | ||
custom: | ||
Issue: "380" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
kind: NOTES | ||
body: 'all: If using terraform-plugin-framework, terraform-plugin-mux, or terraform-plugin-sdk, | ||
only upgrade this Go module when upgrading those Go modules to [email protected], | ||
[email protected], and terraform-plugin-sdk/[email protected], or greater, respectively' | ||
time: 2024-02-22T08:08:18.434191Z | ||
custom: | ||
Issue: "380" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package tfprotov5 | ||
|
||
// FunctionError is used to convey information back to the user running Terraform. | ||
type FunctionError struct { | ||
// Text is the description of the error. | ||
Text string | ||
|
||
// FunctionArgument is the positional function argument for aligning | ||
// configuration source. | ||
FunctionArgument *int64 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
// Package funcerr contains function error helpers. These implementations are | ||
// intentionally outside the public API. | ||
package funcerr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package funcerr | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/hashicorp/terraform-plugin-go/internal/logging" | ||
"github.com/hashicorp/terraform-plugin-go/tfprotov5" | ||
) | ||
|
||
// FunctionError is a single FunctionError. | ||
type FunctionError tfprotov5.FunctionError | ||
|
||
// HasError returns true if the FunctionError is not empty. | ||
func (e *FunctionError) HasError() bool { | ||
if e == nil { | ||
return false | ||
} | ||
|
||
return e.Text != "" || e.FunctionArgument != nil | ||
} | ||
|
||
// Log will log the function error: | ||
func (e *FunctionError) Log(ctx context.Context) { | ||
if e == nil { | ||
return | ||
} | ||
|
||
if !e.HasError() { | ||
return | ||
} | ||
|
||
switch { | ||
case e.FunctionArgument != nil && e.Text != "": | ||
logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ | ||
logging.KeyFunctionErrorText: e.Text, | ||
logging.KeyFunctionErrorArgument: *e.FunctionArgument, | ||
}) | ||
case e.FunctionArgument != nil: | ||
logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ | ||
logging.KeyFunctionErrorArgument: *e.FunctionArgument, | ||
}) | ||
case e.Text != "": | ||
logging.ProtocolError(ctx, "Response contains function error", map[string]interface{}{ | ||
logging.KeyFunctionErrorText: e.Text, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package funcerr_test | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/hashicorp/terraform-plugin-log/tfsdklog" | ||
"github.com/hashicorp/terraform-plugin-log/tfsdklogtest" | ||
|
||
"github.com/hashicorp/terraform-plugin-go/internal/logging" | ||
"github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/funcerr" | ||
) | ||
|
||
func TestFunctionErrorHasError(t *testing.T) { | ||
t.Parallel() | ||
|
||
testCases := map[string]struct { | ||
functionError *funcerr.FunctionError | ||
expected bool | ||
}{ | ||
"nil": { | ||
functionError: nil, | ||
expected: false, | ||
}, | ||
"empty": { | ||
functionError: &funcerr.FunctionError{}, | ||
expected: false, | ||
}, | ||
"argument": { | ||
functionError: &funcerr.FunctionError{ | ||
FunctionArgument: pointer(int64(0)), | ||
}, | ||
expected: true, | ||
}, | ||
"message": { | ||
functionError: &funcerr.FunctionError{ | ||
Text: "test function error", | ||
}, | ||
expected: true, | ||
}, | ||
"argument-and-message": { | ||
functionError: &funcerr.FunctionError{ | ||
FunctionArgument: pointer(int64(0)), | ||
Text: "test function error", | ||
}, | ||
expected: true, | ||
}, | ||
} | ||
|
||
for name, testCase := range testCases { | ||
name, testCase := name, testCase | ||
|
||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
got := testCase.functionError.HasError() | ||
|
||
if diff := cmp.Diff(got, testCase.expected); diff != "" { | ||
t.Errorf("unexpected difference: %s", diff) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestFunctionErrorLog(t *testing.T) { | ||
t.Parallel() | ||
|
||
testCases := map[string]struct { | ||
functionError *funcerr.FunctionError | ||
expected []map[string]interface{} | ||
}{ | ||
"nil": { | ||
functionError: nil, | ||
expected: nil, | ||
}, | ||
"empty": { | ||
functionError: &funcerr.FunctionError{}, | ||
expected: nil, | ||
}, | ||
"argument": { | ||
functionError: &funcerr.FunctionError{ | ||
FunctionArgument: pointer(int64(0)), | ||
}, | ||
expected: []map[string]interface{}{ | ||
{ | ||
"@level": "error", | ||
"@message": "Response contains function error", | ||
"@module": "sdk.proto", | ||
"function_error_argument": float64(0), | ||
}, | ||
}, | ||
}, | ||
"message": { | ||
functionError: &funcerr.FunctionError{ | ||
Text: "test function error", | ||
}, | ||
expected: []map[string]interface{}{ | ||
{ | ||
"@level": "error", | ||
"@message": "Response contains function error", | ||
"@module": "sdk.proto", | ||
"function_error_text": "test function error", | ||
}, | ||
}, | ||
}, | ||
"argument-and-message": { | ||
functionError: &funcerr.FunctionError{ | ||
FunctionArgument: pointer(int64(0)), | ||
Text: "test function error", | ||
}, | ||
expected: []map[string]interface{}{ | ||
{ | ||
"@level": "error", | ||
"@message": "Response contains function error", | ||
"@module": "sdk.proto", | ||
"function_error_text": "test function error", | ||
"function_error_argument": float64(0), | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
for name, testCase := range testCases { | ||
name, testCase := name, testCase | ||
|
||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
var output bytes.Buffer | ||
|
||
ctx := tfsdklogtest.RootLogger(context.Background(), &output) | ||
ctx = logging.ProtoSubsystemContext(ctx, tfsdklog.Options{}) | ||
|
||
testCase.functionError.Log(ctx) | ||
|
||
entries, err := tfsdklogtest.MultilineJSONDecode(&output) | ||
|
||
if err != nil { | ||
t.Fatalf("unable to read multiple line JSON: %s", err) | ||
} | ||
|
||
if diff := cmp.Diff(entries, testCase.expected); diff != "" { | ||
t.Errorf("unexpected difference: %s", diff) | ||
} | ||
}) | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
tfprotov5/internal/toproto/pointer_test.go → tfprotov5/internal/funcerr/pointer_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.