From a51cfff1d783dfe92762adf6285d9b909b8330da Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Fri, 3 Feb 2023 16:52:36 -0500 Subject: [PATCH 1/6] add `listvalidator` and diag helper --- helpers/validatordiag/diag.go | 9 +++++ listvalidator/not_null.go | 42 ++++++++++++++++++++ listvalidator/not_null_test.go | 72 ++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 listvalidator/not_null.go create mode 100644 listvalidator/not_null_test.go diff --git a/helpers/validatordiag/diag.go b/helpers/validatordiag/diag.go index 66db1417..903e0c11 100644 --- a/helpers/validatordiag/diag.go +++ b/helpers/validatordiag/diag.go @@ -9,6 +9,15 @@ import ( "github.com/hashicorp/terraform-plugin-framework/path" ) +// InvalidAttributeDiagnostic returns an error Diagnostic to be used when an attribute is invalid, but has no value. +func InvalidAttributeDiagnostic(path path.Path, description string) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + path, + "Invalid Attribute", + fmt.Sprintf("Attribute %s %s", path, description), + ) +} + // InvalidAttributeValueDiagnostic returns an error Diagnostic to be used when an attribute has an invalid value. func InvalidAttributeValueDiagnostic(path path.Path, description string, value string) diag.Diagnostic { return diag.NewAttributeErrorDiagnostic( diff --git a/listvalidator/not_null.go b/listvalidator/not_null.go new file mode 100644 index 00000000..da1ba0e9 --- /dev/null +++ b/listvalidator/not_null.go @@ -0,0 +1,42 @@ +package listvalidator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.List = notNullValidator{} + +// notNullValidator validates that list is not null +type notNullValidator struct{} + +// Description describes the validation in plain text formatting. +func (v notNullValidator) Description(_ context.Context) string { + return "list must not be null" +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (v notNullValidator) MarkdownDescription(ctx context.Context) string { + return v.Description(ctx) +} + +// Validate performs the validation. +func (v notNullValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { + if req.ConfigValue.IsNull() { + resp.Diagnostics.Append(validatordiag.InvalidAttributeDiagnostic( + req.Path, + v.Description(ctx), + )) + } +} + +// NotNull returns a validator which ensures that any configured list is set +// to a value. +// +// This validator is equivalent to the `Required` field on attributes and is only +// practical for use with `schema.ListNestedBlock` +func NotNull() validator.List { + return notNullValidator{} +} diff --git a/listvalidator/not_null_test.go b/listvalidator/not_null_test.go new file mode 100644 index 00000000..f07fefb1 --- /dev/null +++ b/listvalidator/not_null_test.go @@ -0,0 +1,72 @@ +package listvalidator + +import ( + "context" + "testing" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestNotNullValidator(t *testing.T) { + t.Parallel() + + type testCase struct { + val types.List + expectError bool + } + tests := map[string]testCase{ + "List null": { + val: types.ListNull( + types.StringType, + ), + expectError: true, + }, + "List unknown": { + val: types.ListUnknown( + types.StringType, + ), + expectError: false, + }, + "List empty": { + val: types.ListValueMust( + types.StringType, + []attr.Value{}, + ), + expectError: false, + }, + "List with elements": { + val: types.ListValueMust( + types.StringType, + []attr.Value{ + types.StringValue("first"), + }, + ), + expectError: false, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + t.Parallel() + request := validator.ListRequest{ + Path: path.Root("test"), + PathExpression: path.MatchRoot("test"), + ConfigValue: test.val, + } + response := validator.ListResponse{} + NotNull().ValidateList(context.TODO(), request, &response) + + if !response.Diagnostics.HasError() && test.expectError { + t.Fatal("expected error, got no error") + } + + if response.Diagnostics.HasError() && !test.expectError { + t.Fatalf("got unexpected error: %s", response.Diagnostics) + } + }) + } +} From 07a366fc258053114c6dcb8da43ed90be843d4ce Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 6 Feb 2023 14:28:36 -0500 Subject: [PATCH 2/6] renamed to is_required --- listvalidator/{not_null.go => is_required.go} | 20 +++++++++---------- .../{not_null_test.go => is_required_test.go} | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) rename listvalidator/{not_null.go => is_required.go} (51%) rename listvalidator/{not_null_test.go => is_required_test.go} (93%) diff --git a/listvalidator/not_null.go b/listvalidator/is_required.go similarity index 51% rename from listvalidator/not_null.go rename to listvalidator/is_required.go index da1ba0e9..83440275 100644 --- a/listvalidator/not_null.go +++ b/listvalidator/is_required.go @@ -7,23 +7,23 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" ) -var _ validator.List = notNullValidator{} +var _ validator.List = isRequiredValidator{} -// notNullValidator validates that list is not null -type notNullValidator struct{} +// isRequiredValidator validates that a list has a configuration value set +type isRequiredValidator struct{} // Description describes the validation in plain text formatting. -func (v notNullValidator) Description(_ context.Context) string { - return "list must not be null" +func (v isRequiredValidator) Description(_ context.Context) string { + return "must have a configuration value set as the provider has marked it as required" } // MarkdownDescription describes the validation in Markdown formatting. -func (v notNullValidator) MarkdownDescription(ctx context.Context) string { +func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { return v.Description(ctx) } // Validate performs the validation. -func (v notNullValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { +func (v isRequiredValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { if req.ConfigValue.IsNull() { resp.Diagnostics.Append(validatordiag.InvalidAttributeDiagnostic( req.Path, @@ -32,11 +32,11 @@ func (v notNullValidator) ValidateList(ctx context.Context, req validator.ListRe } } -// NotNull returns a validator which ensures that any configured list is set +// IsRequired returns a validator which ensures that any configured list is set // to a value. // // This validator is equivalent to the `Required` field on attributes and is only // practical for use with `schema.ListNestedBlock` -func NotNull() validator.List { - return notNullValidator{} +func IsRequired() validator.List { + return isRequiredValidator{} } diff --git a/listvalidator/not_null_test.go b/listvalidator/is_required_test.go similarity index 93% rename from listvalidator/not_null_test.go rename to listvalidator/is_required_test.go index f07fefb1..fbf17d7a 100644 --- a/listvalidator/not_null_test.go +++ b/listvalidator/is_required_test.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" ) -func TestNotNullValidator(t *testing.T) { +func TestIsRequiredValidator(t *testing.T) { t.Parallel() type testCase struct { @@ -58,7 +58,7 @@ func TestNotNullValidator(t *testing.T) { ConfigValue: test.val, } response := validator.ListResponse{} - NotNull().ValidateList(context.TODO(), request, &response) + IsRequired().ValidateList(context.TODO(), request, &response) if !response.Diagnostics.HasError() && test.expectError { t.Fatal("expected error, got no error") From 1209d88bf095fe29c7af3a41691d1134d9e6ac08 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 6 Feb 2023 14:41:28 -0500 Subject: [PATCH 3/6] add set validator --- listvalidator/is_required.go | 7 ++-- setvalidator/is_required.go | 41 ++++++++++++++++++ setvalidator/is_required_test.go | 72 ++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 setvalidator/is_required.go create mode 100644 setvalidator/is_required_test.go diff --git a/listvalidator/is_required.go b/listvalidator/is_required.go index 83440275..59f7bc3c 100644 --- a/listvalidator/is_required.go +++ b/listvalidator/is_required.go @@ -9,12 +9,12 @@ import ( var _ validator.List = isRequiredValidator{} -// isRequiredValidator validates that a list has a configuration value set +// isRequiredValidator validates that a list has a configuration value. type isRequiredValidator struct{} // Description describes the validation in plain text formatting. func (v isRequiredValidator) Description(_ context.Context) string { - return "must have a configuration value set as the provider has marked it as required" + return "must have a configuration value as the provider has marked it as required" } // MarkdownDescription describes the validation in Markdown formatting. @@ -32,8 +32,7 @@ func (v isRequiredValidator) ValidateList(ctx context.Context, req validator.Lis } } -// IsRequired returns a validator which ensures that any configured list is set -// to a value. +// IsRequired returns a validator which ensures that any configured list has a value (not null). // // This validator is equivalent to the `Required` field on attributes and is only // practical for use with `schema.ListNestedBlock` diff --git a/setvalidator/is_required.go b/setvalidator/is_required.go new file mode 100644 index 00000000..c019b0b8 --- /dev/null +++ b/setvalidator/is_required.go @@ -0,0 +1,41 @@ +package setvalidator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.Set = isRequiredValidator{} + +// isRequiredValidator validates that a set has a configuration value. +type isRequiredValidator struct{} + +// Description describes the validation in plain text formatting. +func (v isRequiredValidator) Description(_ context.Context) string { + return "must have a configuration value as the provider has marked it as required" +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { + return v.Description(ctx) +} + +// Validate performs the validation. +func (v isRequiredValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) { + if req.ConfigValue.IsNull() { + resp.Diagnostics.Append(validatordiag.InvalidAttributeDiagnostic( + req.Path, + v.Description(ctx), + )) + } +} + +// IsRequired returns a validator which ensures that any configured set has a value (not null). +// +// This validator is equivalent to the `Required` field on attributes and is only +// practical for use with `schema.SetNestedBlock` +func IsRequired() validator.Set { + return isRequiredValidator{} +} diff --git a/setvalidator/is_required_test.go b/setvalidator/is_required_test.go new file mode 100644 index 00000000..d79cdcc5 --- /dev/null +++ b/setvalidator/is_required_test.go @@ -0,0 +1,72 @@ +package setvalidator + +import ( + "context" + "testing" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestIsRequiredValidator(t *testing.T) { + t.Parallel() + + type testCase struct { + val types.Set + expectError bool + } + tests := map[string]testCase{ + "Set null": { + val: types.SetNull( + types.StringType, + ), + expectError: true, + }, + "Set unknown": { + val: types.SetUnknown( + types.StringType, + ), + expectError: false, + }, + "Set empty": { + val: types.SetValueMust( + types.StringType, + []attr.Value{}, + ), + expectError: false, + }, + "Set with elements": { + val: types.SetValueMust( + types.StringType, + []attr.Value{ + types.StringValue("first"), + }, + ), + expectError: false, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + t.Parallel() + request := validator.SetRequest{ + Path: path.Root("test"), + PathExpression: path.MatchRoot("test"), + ConfigValue: test.val, + } + response := validator.SetResponse{} + IsRequired().ValidateSet(context.TODO(), request, &response) + + if !response.Diagnostics.HasError() && test.expectError { + t.Fatal("expected error, got no error") + } + + if response.Diagnostics.HasError() && !test.expectError { + t.Fatalf("got unexpected error: %s", response.Diagnostics) + } + }) + } +} From 6b103a6797b4398bf0939d7f2a7e3a02cd267a50 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 6 Feb 2023 15:42:35 -0500 Subject: [PATCH 4/6] added object validator --- listvalidator/is_required_test.go | 5 +- objectvalidator/is_required.go | 41 ++++++++++++++ objectvalidator/is_required_test.go | 83 +++++++++++++++++++++++++++++ setvalidator/is_required_test.go | 5 +- 4 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 objectvalidator/is_required.go create mode 100644 objectvalidator/is_required_test.go diff --git a/listvalidator/is_required_test.go b/listvalidator/is_required_test.go index fbf17d7a..b549f3d9 100644 --- a/listvalidator/is_required_test.go +++ b/listvalidator/is_required_test.go @@ -1,9 +1,10 @@ -package listvalidator +package listvalidator_test import ( "context" "testing" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -58,7 +59,7 @@ func TestIsRequiredValidator(t *testing.T) { ConfigValue: test.val, } response := validator.ListResponse{} - IsRequired().ValidateList(context.TODO(), request, &response) + listvalidator.IsRequired().ValidateList(context.TODO(), request, &response) if !response.Diagnostics.HasError() && test.expectError { t.Fatal("expected error, got no error") diff --git a/objectvalidator/is_required.go b/objectvalidator/is_required.go new file mode 100644 index 00000000..9db53b9d --- /dev/null +++ b/objectvalidator/is_required.go @@ -0,0 +1,41 @@ +package objectvalidator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.Object = isRequiredValidator{} + +// isRequiredValidator validates that an object has a configuration value. +type isRequiredValidator struct{} + +// Description describes the validation in plain text formatting. +func (v isRequiredValidator) Description(_ context.Context) string { + return "must have a configuration value as the provider has marked it as required" +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { + return v.Description(ctx) +} + +// Validate performs the validation. +func (v isRequiredValidator) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { + if req.ConfigValue.IsNull() { + resp.Diagnostics.Append(validatordiag.InvalidAttributeDiagnostic( + req.Path, + v.Description(ctx), + )) + } +} + +// IsRequired returns a validator which ensures that any configured object has a value (not null). +// +// This validator is equivalent to the `Required` field on attributes and is only +// practical for use with `schema.SingleNestedBlock` or `schema.NestedBlockObject` +func IsRequired() validator.Object { + return isRequiredValidator{} +} diff --git a/objectvalidator/is_required_test.go b/objectvalidator/is_required_test.go new file mode 100644 index 00000000..e4fd7bd3 --- /dev/null +++ b/objectvalidator/is_required_test.go @@ -0,0 +1,83 @@ +package objectvalidator_test + +import ( + "context" + "testing" + + "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestIsRequiredValidator(t *testing.T) { + t.Parallel() + + type testCase struct { + val types.Object + expectError bool + } + tests := map[string]testCase{ + "Object null": { + val: types.ObjectNull( + map[string]attr.Type{ + "field1": types.StringType, + }, + ), + expectError: true, + }, + "Object unknown": { + val: types.ObjectUnknown( + map[string]attr.Type{ + "field1": types.StringType, + }, + ), + expectError: false, + }, + "Object empty": { + val: types.ObjectValueMust( + map[string]attr.Type{ + "field1": types.StringType, + }, + map[string]attr.Value{ + "field1": types.StringNull(), + }, + ), + expectError: false, + }, + "Object with elements": { + val: types.ObjectValueMust( + map[string]attr.Type{ + "field1": types.StringType, + }, + map[string]attr.Value{ + "field1": types.StringValue("value1"), + }, + ), + expectError: false, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + t.Parallel() + request := validator.ObjectRequest{ + Path: path.Root("test"), + PathExpression: path.MatchRoot("test"), + ConfigValue: test.val, + } + response := validator.ObjectResponse{} + objectvalidator.IsRequired().ValidateObject(context.TODO(), request, &response) + + if !response.Diagnostics.HasError() && test.expectError { + t.Fatal("expected error, got no error") + } + + if response.Diagnostics.HasError() && !test.expectError { + t.Fatalf("got unexpected error: %s", response.Diagnostics) + } + }) + } +} diff --git a/setvalidator/is_required_test.go b/setvalidator/is_required_test.go index d79cdcc5..b5e8356f 100644 --- a/setvalidator/is_required_test.go +++ b/setvalidator/is_required_test.go @@ -1,9 +1,10 @@ -package setvalidator +package setvalidator_test import ( "context" "testing" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -58,7 +59,7 @@ func TestIsRequiredValidator(t *testing.T) { ConfigValue: test.val, } response := validator.SetResponse{} - IsRequired().ValidateSet(context.TODO(), request, &response) + setvalidator.IsRequired().ValidateSet(context.TODO(), request, &response) if !response.Diagnostics.HasError() && test.expectError { t.Fatal("expected error, got no error") From 33330032d410b62270ed6e5ee4b154a7291ffd37 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 6 Feb 2023 15:50:33 -0500 Subject: [PATCH 5/6] renamed to block --- helpers/validatordiag/diag.go | 8 ++++---- listvalidator/is_required.go | 2 +- objectvalidator/is_required.go | 2 +- setvalidator/is_required.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/helpers/validatordiag/diag.go b/helpers/validatordiag/diag.go index 903e0c11..60ca1e79 100644 --- a/helpers/validatordiag/diag.go +++ b/helpers/validatordiag/diag.go @@ -9,12 +9,12 @@ import ( "github.com/hashicorp/terraform-plugin-framework/path" ) -// InvalidAttributeDiagnostic returns an error Diagnostic to be used when an attribute is invalid, but has no value. -func InvalidAttributeDiagnostic(path path.Path, description string) diag.Diagnostic { +// InvalidBlockDiagnostic returns an error Diagnostic to be used when a block is invalid +func InvalidBlockDiagnostic(path path.Path, description string) diag.Diagnostic { return diag.NewAttributeErrorDiagnostic( path, - "Invalid Attribute", - fmt.Sprintf("Attribute %s %s", path, description), + "Invalid Block", + fmt.Sprintf("Block %s %s", path, description), ) } diff --git a/listvalidator/is_required.go b/listvalidator/is_required.go index 59f7bc3c..c97e67c6 100644 --- a/listvalidator/is_required.go +++ b/listvalidator/is_required.go @@ -25,7 +25,7 @@ func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { // Validate performs the validation. func (v isRequiredValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { if req.ConfigValue.IsNull() { - resp.Diagnostics.Append(validatordiag.InvalidAttributeDiagnostic( + resp.Diagnostics.Append(validatordiag.InvalidBlockDiagnostic( req.Path, v.Description(ctx), )) diff --git a/objectvalidator/is_required.go b/objectvalidator/is_required.go index 9db53b9d..d2c41525 100644 --- a/objectvalidator/is_required.go +++ b/objectvalidator/is_required.go @@ -25,7 +25,7 @@ func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { // Validate performs the validation. func (v isRequiredValidator) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { if req.ConfigValue.IsNull() { - resp.Diagnostics.Append(validatordiag.InvalidAttributeDiagnostic( + resp.Diagnostics.Append(validatordiag.InvalidBlockDiagnostic( req.Path, v.Description(ctx), )) diff --git a/setvalidator/is_required.go b/setvalidator/is_required.go index c019b0b8..d831563c 100644 --- a/setvalidator/is_required.go +++ b/setvalidator/is_required.go @@ -25,7 +25,7 @@ func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { // Validate performs the validation. func (v isRequiredValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) { if req.ConfigValue.IsNull() { - resp.Diagnostics.Append(validatordiag.InvalidAttributeDiagnostic( + resp.Diagnostics.Append(validatordiag.InvalidBlockDiagnostic( req.Path, v.Description(ctx), )) From 25bada52026a449ef7548a227b9749aabab64281 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 6 Feb 2023 17:16:08 -0500 Subject: [PATCH 6/6] added examples and removed line in comment --- listvalidator/is_required_example_test.go | 28 +++++++++++++++++++++ objectvalidator/is_required.go | 2 +- objectvalidator/is_required_example_test.go | 26 +++++++++++++++++++ setvalidator/is_required_example_test.go | 28 +++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 listvalidator/is_required_example_test.go create mode 100644 objectvalidator/is_required_example_test.go create mode 100644 setvalidator/is_required_example_test.go diff --git a/listvalidator/is_required_example_test.go b/listvalidator/is_required_example_test.go new file mode 100644 index 00000000..36d41c33 --- /dev/null +++ b/listvalidator/is_required_example_test.go @@ -0,0 +1,28 @@ +package listvalidator_test + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +func ExampleIsRequired() { + // Used within a Schema method of a DataSource, Provider, or Resource + _ = schema.Schema{ + Blocks: map[string]schema.Block{ + "example_block": schema.ListNestedBlock{ + Validators: []validator.List{ + // Validate this block has a value (not null). + listvalidator.IsRequired(), + }, + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "example_string_attribute": schema.StringAttribute{ + Required: true, + }, + }, + }, + }, + }, + } +} diff --git a/objectvalidator/is_required.go b/objectvalidator/is_required.go index d2c41525..e074fd35 100644 --- a/objectvalidator/is_required.go +++ b/objectvalidator/is_required.go @@ -35,7 +35,7 @@ func (v isRequiredValidator) ValidateObject(ctx context.Context, req validator.O // IsRequired returns a validator which ensures that any configured object has a value (not null). // // This validator is equivalent to the `Required` field on attributes and is only -// practical for use with `schema.SingleNestedBlock` or `schema.NestedBlockObject` +// practical for use with `schema.SingleNestedBlock` func IsRequired() validator.Object { return isRequiredValidator{} } diff --git a/objectvalidator/is_required_example_test.go b/objectvalidator/is_required_example_test.go new file mode 100644 index 00000000..6b049cc3 --- /dev/null +++ b/objectvalidator/is_required_example_test.go @@ -0,0 +1,26 @@ +package objectvalidator_test + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +func ExampleIsRequired() { + // Used within a Schema method of a DataSource, Provider, or Resource + _ = schema.Schema{ + Blocks: map[string]schema.Block{ + "example_block": schema.SingleNestedBlock{ + Validators: []validator.Object{ + // Validate this block has a value (not null). + objectvalidator.IsRequired(), + }, + Attributes: map[string]schema.Attribute{ + "example_string_attribute": schema.StringAttribute{ + Required: true, + }, + }, + }, + }, + } +} diff --git a/setvalidator/is_required_example_test.go b/setvalidator/is_required_example_test.go new file mode 100644 index 00000000..7447cb3b --- /dev/null +++ b/setvalidator/is_required_example_test.go @@ -0,0 +1,28 @@ +package setvalidator_test + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +func ExampleIsRequired() { + // Used within a Schema method of a DataSource, Provider, or Resource + _ = schema.Schema{ + Blocks: map[string]schema.Block{ + "example_block": schema.SetNestedBlock{ + Validators: []validator.Set{ + // Validate this block has a value (not null). + setvalidator.IsRequired(), + }, + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "example_string_attribute": schema.StringAttribute{ + Required: true, + }, + }, + }, + }, + }, + } +}