Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parameter-based provider-defined function validation #971

Merged
merged 73 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
5930e21
Add ValidateableAttribute and ValidateableParameter interfaces
bendbennett Mar 19, 2024
e3b5956
Deprecate xattr.TypeWithValidate
bendbennett Mar 19, 2024
a285776
Merge remote-tracking branch 'origin/main' into bendbennett/pdf-param…
bendbennett Mar 21, 2024
30cc1d9
Modify function signature of ArgumentsData() to return a function.Fun…
bendbennett Mar 21, 2024
b87d7ee
Modify Data.SetAtPath to use switch statement to handle validation.Va…
bendbennett Mar 21, 2024
cc06028
Modify Data.SetAtPathTransformFunc to use switch statement to handle …
bendbennett Mar 21, 2024
cf60c85
Temporarily moving ValidateableAttribute interface to xattr package t…
bendbennett Mar 22, 2024
995b96c
Adding test coverage for list, map and set for SetAtPathTransformFunc
bendbennett Mar 22, 2024
fe30c12
Adding test coverage for bool ValidateableParameter for fromproto5/6 …
bendbennett Mar 22, 2024
7328488
Adding switch statement for ValidateableAttribute to fwschemadata Dat…
bendbennett Mar 22, 2024
2437643
Merge remote-tracking branch 'origin/main' into bendbennett/pdf-param…
bendbennett Mar 22, 2024
b27c7fa
Adding switch statements to internal/reflect/interfaces to handle Val…
bendbennett Mar 22, 2024
a8103f6
Fix usage of incorrect test type
bendbennett Mar 22, 2024
06a5b87
Adding switch statements to internal/reflect/primitive to handle Vali…
bendbennett Mar 22, 2024
f410606
Renaming interfaces
bendbennett Mar 22, 2024
90dd543
Add `function/validator` package
SBGoods Mar 29, 2024
fc554ab
Implement parameter validators in parameter types
SBGoods Mar 29, 2024
75fb708
Initial implementation of parameter validation logic
SBGoods Mar 29, 2024
240679a
Refactor function parameter validators from `function/validator` pack…
SBGoods Mar 29, 2024
3dac93f
Add parameter unit tests
SBGoods Mar 29, 2024
fb0d4fc
Add parameter tests to arguments_data_test.go
SBGoods Apr 1, 2024
bab78d4
Add Equal() methods to ListValueWithValidateAttributeWarning and MapV…
bendbennett Apr 2, 2024
50c673a
Adding switch statements to reflect package FromMap() function to han…
bendbennett Apr 2, 2024
e0017b0
Adding switch statements to reflect package FromInt(), FromUint(), Fr…
bendbennett Apr 2, 2024
1d2c768
Adding switch statements to reflect package FromPointer() function to…
bendbennett Apr 2, 2024
12dcc5c
Adding switch statements to reflect package FromSlice() function to h…
bendbennett Apr 2, 2024
ce4b934
Adding switch statements to reflect package FromStruct() function to …
bendbennett Apr 2, 2024
7df6872
Switch dynamic parameter test to use `DynamicTypeMust()`
SBGoods Apr 2, 2024
bb76e62
Merge remote-tracking branch 'origin/main' into bendbennett/pdf-param…
bendbennett Apr 3, 2024
d04737c
fromproto5+fromproto6: Add further test coverage for validation of fu…
bendbennett Apr 3, 2024
b6d8b93
xfwfunction: Moving Definition.Parameter() method from function packa…
bendbennett Apr 3, 2024
3e0bc53
fromproto5+fromproto6: Fix function error message in ArgumentsData()
bendbennett Apr 3, 2024
c8fd898
Correct error handling and dynamic type test cases
SBGoods Apr 4, 2024
6de0382
website: Add documentation for usage of xattr.ValidateableAttribute a…
bendbennett Apr 4, 2024
c8b530b
Merge remote-tracking branch 'origin/main' into bendbennett/pdf-param…
bendbennett Apr 4, 2024
ebea449
website: Add documentation for usage of xattr.ValidateableAttribute a…
bendbennett Apr 4, 2024
399acd1
Adding changelog entries
bendbennett Apr 4, 2024
07511f6
Add variadic parameter test cases
SBGoods Apr 4, 2024
90b8f4b
Add variadic parameter support and test for `tfprotov6`
SBGoods Apr 4, 2024
2092648
Add copyright headers
SBGoods Apr 4, 2024
b73c0ef
Resolve `forcetypeassert` linter errors
SBGoods Apr 4, 2024
7478bfc
Merge remote-tracking branch 'origin/bendbennett/pdf-parameter-type-v…
SBGoods Apr 4, 2024
01321ea
Resolve test failures from merge
SBGoods Apr 4, 2024
6a32373
function: Remove unused Definition.Parameter() method
bendbennett Apr 5, 2024
c758c9c
attr/xattr: Remove TODO
bendbennett Apr 5, 2024
fb75b19
attr/xattr: Modify deprecation comment
bendbennett Apr 5, 2024
6f49065
fwschemadata: Reordering logging calls
bendbennett Apr 5, 2024
bb5d344
Merge branch 'bendbennett/pdf-parameter-type-validation' into SBGoods…
SBGoods Apr 5, 2024
288078a
Add changelog entries
SBGoods Apr 5, 2024
8ba70f0
Merge remote-tracking branch 'origin/SBGoods/pdf-parameter-type-valid…
SBGoods Apr 5, 2024
dcdc8ee
Skip appending parameter value if validation fails
SBGoods Apr 8, 2024
e26cde9
fromproto5+fromproto6: Inline logic from Parameter() function in Argu…
bendbennett Apr 9, 2024
24db3f2
Remove value type-specific interfaces for <Type>ValuableWithValidatea…
bendbennett Apr 9, 2024
6283788
website: Adding documentation for parameter validation into parameter…
bendbennett Apr 9, 2024
83293bd
function: Moving ValidateableParameter interface to function package
bendbennett Apr 9, 2024
75e30e5
Amend docs
bendbennett Apr 9, 2024
6c517b1
Apply suggestions from code review
bendbennett Apr 9, 2024
c55b74b
fromproto5: Remove unused function
bendbennett Apr 9, 2024
0d3ff07
fromproto5+fromproto6: Remove unneeded case statements
bendbennett Apr 9, 2024
cf398ce
fromproto5: Removing errant test case
bendbennett Apr 9, 2024
1f79cbb
Support parameter validation for custom types
SBGoods Apr 9, 2024
6fce33c
Refactor parameter validator interface names for clarity.
SBGoods Apr 9, 2024
fe52c08
Merge branch 'bendbennett/pdf-parameter-type-validation' into SBGoods…
SBGoods Apr 9, 2024
a39677d
Add website documentation for parameter-based validation
SBGoods Apr 9, 2024
e31bd0d
Add copyright headers
SBGoods Apr 9, 2024
ef737ac
Update changelog entries
SBGoods Apr 9, 2024
87b145b
Rename `Validate()` method in parameter validator interfaces to `Vali…
SBGoods Apr 11, 2024
e74e3e7
Merge branch 'main' into SBGoods/pdf-parameter-type-validation
SBGoods Apr 12, 2024
851ee46
Skip appending variadic values if there is an error in validation
SBGoods Apr 12, 2024
b962441
Update website/docs/plugin/framework/validation.mdx
SBGoods Apr 15, 2024
8dafce5
Replace `create{type}Value` test helper functions with `New{Type}Valu…
SBGoods Apr 15, 2024
5b3f0b8
Merge remote-tracking branch 'origin/SBGoods/pdf-parameter-type-valid…
SBGoods Apr 15, 2024
3dcd2e0
Merge branch 'main' into SBGoods/pdf-parameter-type-validation
SBGoods Apr 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changes/unreleased/FEATURES-20240405-183917.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: FEATURES
body: '`function`: Add `BoolParameterValidator`, `DynamicParameterValidator`, `Float64ParameterValidator`, `Int64ParameterValidator`,
`ListParameterValidator`, `MapParameterValidator`, `NumberParameterValidator`, `ObjectParameterValidator`, `SetParameterValidator`,
and `StringParameterValidator` interfaces for custom function parameter validation implementations.'
time: 2024-04-05T18:39:17.640444-04:00
custom:
Issue: "971"
9 changes: 9 additions & 0 deletions .changes/unreleased/FEATURES-20240405-184527.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
kind: FEATURES
body: '`function`: Add `ParameterWithBoolValidators`, `ParameterWithInt64Validators`,
`ParameterWithFloat64Validators`, `ParameterWithDynamicValidators`, `ParameterWithListValidators`,
`ParameterWithMapValidators`, `ParameterWithNumberValidators`, `ParameterWithObjectValidators`,
`ParameterWithSetValidators`, and `ParameterWithStringValidators` interfaces to enable
parameter-based validation support'
time: 2024-04-05T18:45:27.979266-04:00
custom:
Issue: "971"
10 changes: 10 additions & 0 deletions function/bool_parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

// Ensure the implementation satisifies the desired interfaces.
var _ Parameter = BoolParameter{}
var _ ParameterWithBoolValidators = BoolParameter{}

// BoolParameter represents a function parameter that is a boolean.
//
Expand Down Expand Up @@ -70,6 +71,15 @@ type BoolParameter struct {
// alphabetical character and followed by alphanumeric or underscore
// characters.
Name string

// Validators is a list of bool validators that should be applied to the
// parameter.
Validators []BoolParameterValidator
}

SBGoods marked this conversation as resolved.
Show resolved Hide resolved
// GetValidators returns the list of validators for the parameter.
func (p BoolParameter) GetValidators() []BoolParameterValidator {
return p.Validators
}

// GetAllowNullValue returns if the parameter accepts a null value.
Expand Down
44 changes: 44 additions & 0 deletions function/bool_parameter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"testing"

"github.com/google/go-cmp/cmp"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/function"
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes"
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testvalidator"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
)

Expand Down Expand Up @@ -240,3 +242,45 @@ func TestBoolParameterGetType(t *testing.T) {
})
}
}

func TestBoolParameterBoolValidators(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
parameter function.BoolParameter
expected []function.BoolParameterValidator
}{
"unset": {
parameter: function.BoolParameter{},
expected: nil,
},
"Validators - empty": {
parameter: function.BoolParameter{
Validators: []function.BoolParameterValidator{}},
expected: []function.BoolParameterValidator{},
},
"Validators": {
parameter: function.BoolParameter{
Validators: []function.BoolParameterValidator{
testvalidator.Bool{},
}},
expected: []function.BoolParameterValidator{
testvalidator.Bool{},
},
},
}

for name, testCase := range testCases {
name, testCase := name, testCase

t.Run(name, func(t *testing.T) {
t.Parallel()

got := testCase.parameter.GetValidators()

if diff := cmp.Diff(got, testCase.expected); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}
33 changes: 33 additions & 0 deletions function/bool_parameter_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package function

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/types"
)

// BoolParameterValidator is a function validator for types.Bool parameters.
type BoolParameterValidator interface {

// ValidateParameterBool performs the validation.
ValidateParameterBool(context.Context, BoolParameterValidatorRequest, *BoolParameterValidatorResponse)
}

// BoolParameterValidatorRequest is a request for types.Bool schema validation.
type BoolParameterValidatorRequest struct {
// ArgumentPosition contains the position of the argument for validation.
// Use this position for any response diagnostics.
ArgumentPosition int64

// Value contains the value of the argument for validation.
Value types.Bool
}

// BoolParameterValidatorResponse is a response to a BoolParameterValidatorRequest.
type BoolParameterValidatorResponse struct {
// Error is a function error generated during validation of the Value.
Error *FuncError
}
10 changes: 10 additions & 0 deletions function/dynamic_parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

// Ensure the implementation satisifies the desired interfaces.
var _ Parameter = DynamicParameter{}
var _ ParameterWithDynamicValidators = DynamicParameter{}

// DynamicParameter represents a function parameter that is a dynamic, rather
// than a static type. Static types are always preferable over dynamic
Expand Down Expand Up @@ -65,6 +66,15 @@ type DynamicParameter struct {
// alphabetical character and followed by alphanumeric or underscore
// characters.
Name string

// Validators is a list of dynamic validators that should be applied to the
// parameter.
Validators []DynamicParameterValidator
}

// GetValidators returns the list of validators for the parameter.
func (p DynamicParameter) GetValidators() []DynamicParameterValidator {
return p.Validators
}

// GetAllowNullValue returns if the parameter accepts a null value.
Expand Down
44 changes: 44 additions & 0 deletions function/dynamic_parameter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"testing"

"github.com/google/go-cmp/cmp"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/function"
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes"
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testvalidator"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
)

Expand Down Expand Up @@ -240,3 +242,45 @@ func TestDynamicParameterGetType(t *testing.T) {
})
}
}

func TestDynamicParameterDynamicValidators(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
parameter function.DynamicParameter
expected []function.DynamicParameterValidator
}{
"unset": {
parameter: function.DynamicParameter{},
expected: nil,
},
"Validators - empty": {
parameter: function.DynamicParameter{
Validators: []function.DynamicParameterValidator{}},
expected: []function.DynamicParameterValidator{},
},
"Validators": {
parameter: function.DynamicParameter{
Validators: []function.DynamicParameterValidator{
testvalidator.Dynamic{},
}},
expected: []function.DynamicParameterValidator{
testvalidator.Dynamic{},
},
},
}

for name, testCase := range testCases {
name, testCase := name, testCase

t.Run(name, func(t *testing.T) {
t.Parallel()

got := testCase.parameter.GetValidators()

if diff := cmp.Diff(got, testCase.expected); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}
33 changes: 33 additions & 0 deletions function/dynamic_parameter_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package function

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/types"
)

// DynamicParameterValidator is a function validator for types.Dynamic parameters.
type DynamicParameterValidator interface {

// ValidateParameterDynamic performs the validation.
ValidateParameterDynamic(context.Context, DynamicParameterValidatorRequest, *DynamicParameterValidatorResponse)
}

// DynamicParameterValidatorRequest is a request for types.Dynamic schema validation.
type DynamicParameterValidatorRequest struct {
// ArgumentPosition contains the position of the argument for validation.
// Use this position for any response diagnostics.
ArgumentPosition int64

// Value contains the value of the argument for validation.
Value types.Dynamic
}

// DynamicParameterValidatorResponse is a response to a DynamicParameterValidatorRequest.
type DynamicParameterValidatorResponse struct {
// Error is a function error generated during validation of the Value.
Error *FuncError
}
10 changes: 10 additions & 0 deletions function/float64_parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

// Ensure the implementation satisifies the desired interfaces.
var _ Parameter = Float64Parameter{}
var _ ParameterWithFloat64Validators = Float64Parameter{}

// Float64Parameter represents a function parameter that is a 64-bit floating
// point number.
Expand Down Expand Up @@ -67,6 +68,15 @@ type Float64Parameter struct {
// alphabetical character and followed by alphanumeric or underscore
// characters.
Name string

// Validators is a list of float64 validators that should be applied to the
// parameter.
Validators []Float64ParameterValidator
}

// GetValidators returns the list of validators for the parameter.
func (p Float64Parameter) GetValidators() []Float64ParameterValidator {
return p.Validators
}

// GetAllowNullValue returns if the parameter accepts a null value.
Expand Down
44 changes: 44 additions & 0 deletions function/float64_parameter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"testing"

"github.com/google/go-cmp/cmp"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/function"
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes"
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testvalidator"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
)

Expand Down Expand Up @@ -240,3 +242,45 @@ func TestFloat64ParameterGetType(t *testing.T) {
})
}
}

func TestFloat64ParameterFloat64Validators(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
parameter function.Float64Parameter
expected []function.Float64ParameterValidator
}{
"unset": {
parameter: function.Float64Parameter{},
expected: nil,
},
"Validators - empty": {
parameter: function.Float64Parameter{
Validators: []function.Float64ParameterValidator{}},
expected: []function.Float64ParameterValidator{},
},
"Validators": {
parameter: function.Float64Parameter{
Validators: []function.Float64ParameterValidator{
testvalidator.Float64{},
}},
expected: []function.Float64ParameterValidator{
testvalidator.Float64{},
},
},
}

for name, testCase := range testCases {
name, testCase := name, testCase

t.Run(name, func(t *testing.T) {
t.Parallel()

got := testCase.parameter.GetValidators()

if diff := cmp.Diff(got, testCase.expected); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}
})
}
}
33 changes: 33 additions & 0 deletions function/float64_parameter_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package function

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/types"
)

// Float64ParameterValidator is a function validator for types.Float64 parameters.
type Float64ParameterValidator interface {

// ValidateParameterFloat64 performs the validation.
ValidateParameterFloat64(context.Context, Float64ParameterValidatorRequest, *Float64ParameterValidatorResponse)
}

// Float64ParameterValidatorRequest is a request for types.Float64 schema validation.
type Float64ParameterValidatorRequest struct {
// ArgumentPosition contains the position of the argument for validation.
// Use this position for any response diagnostics.
ArgumentPosition int64

// Value contains the value of the argument for validation.
Value types.Float64
}

// Float64ParameterValidatorResponse is a response to a Float64ParameterValidatorRequest.
type Float64ParameterValidatorResponse struct {
// Error is a function error generated during validation of the Value.
Error *FuncError
}
10 changes: 10 additions & 0 deletions function/int64_parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

// Ensure the implementation satisifies the desired interfaces.
var _ Parameter = Int64Parameter{}
var _ ParameterWithInt64Validators = Int64Parameter{}

// Int64Parameter represents a function parameter that is a 64-bit integer.
//
Expand Down Expand Up @@ -66,6 +67,15 @@ type Int64Parameter struct {
// alphabetical character and followed by alphanumeric or underscore
// characters.
Name string

// Validators is a list of int64 validators that should be applied to the
// parameter.
Validators []Int64ParameterValidator
}

// GetValidators returns the list of validators for the parameter.
func (p Int64Parameter) GetValidators() []Int64ParameterValidator {
return p.Validators
}

// GetAllowNullValue returns if the parameter accepts a null value.
Expand Down
Loading
Loading