Skip to content

Commit

Permalink
all: Convert empty list and set block values to null (hashicorp#604)
Browse files Browse the repository at this point in the history
Reference: hashicorp#601
Reference: hashicorp#606
  • Loading branch information
bflad authored Jan 6, 2023
1 parent 51bb0a7 commit faab4e3
Show file tree
Hide file tree
Showing 24 changed files with 4,552 additions and 66 deletions.
19 changes: 19 additions & 0 deletions .changelog/604.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
```release-note:note
all: For data handling consistency with attributes, unconfigured list and set blocks will now be represented as a null list or set instead of a known list or set with zero elements. This prevents confusing situations with validation and plan modification, where it was previously required to check block values for the number of elements. Logic that was previously missing null value checks for blocks may require updates.
```

```release-note:enhancement
path: Added `Expressions` type `Matches` method for checking if any expression in the collection matches a given path
```

```release-note:bug
datasource/schema: Prevented `ListNestedBlock` and `SetNestedBlock` type `DeprecationMessage` field from causing `Block Deprecated` warnings with unconfigured blocks
```

```release-note:bug
provider/schema: Prevented `ListNestedBlock` and `SetNestedBlock` type `DeprecationMessage` field from causing `Block Deprecated` warnings with unconfigured blocks
```

```release-note:bug
resource/schema: Prevented `ListNestedBlock` and `SetNestedBlock` type `DeprecationMessage` field from causing `Block Deprecated` warnings with unconfigured blocks
```
16 changes: 6 additions & 10 deletions internal/fromproto5/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)
Expand Down Expand Up @@ -32,23 +33,18 @@ func Config(ctx context.Context, proto5DynamicValue *tfprotov5.DynamicValue, sch
return nil, diags
}

proto5Value, err := proto5DynamicValue.Unmarshal(schema.Type().TerraformType(ctx))
data, dynamicValueDiags := DynamicValue(ctx, proto5DynamicValue, schema, fwschemadata.DataDescriptionConfiguration)

if err != nil {
diags.AddError(
"Unable to Convert Configuration",
"An unexpected error was encountered when converting the configuration from the protocol type. "+
"This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+
"Please report this to the provider developer:\n\n"+err.Error(),
)
diags.Append(dynamicValueDiags...)

if diags.HasError() {
return nil, diags
}

fw := &tfsdk.Config{
Raw: proto5Value,
Raw: data.TerraformValue,
Schema: schema,
}

return fw, nil
return fw, diags
}
2 changes: 1 addition & 1 deletion internal/fromproto5/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func TestConfig(t *testing.T) {
"An unexpected error was encountered when converting the configuration from the protocol type. "+
"This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+
"Please report this to the provider developer:\n\n"+
"AttributeName(\"test_attribute\"): couldn't decode bool: msgpack: invalid code=aa decoding bool",
"Unable to unmarshal DynamicValue: AttributeName(\"test_attribute\"): couldn't decode bool: msgpack: invalid code=aa decoding bool",
),
},
},
Expand Down
53 changes: 53 additions & 0 deletions internal/fromproto5/dynamic_value.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package fromproto5

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

// DynamicValue returns the fwschemadata.Data for a given
// *tfprotov5.DynamicValue.
//
// If necessary, the underlying data is modified to convert list and set block
// values from an empty collection to a null collection. This is to prevent
// developers from needing to understand Terraform's differences between
// block and attribute values where blocks are technically never null, but from
// a developer perspective this distinction introduces unnecessary complexity.
// This null block value translation is automatically handled by Terraform from
// provider responses.
func DynamicValue(ctx context.Context, proto5 *tfprotov5.DynamicValue, schema fwschema.Schema, description fwschemadata.DataDescription) (fwschemadata.Data, diag.Diagnostics) {
var diags diag.Diagnostics

data := &fwschemadata.Data{
Description: description,
Schema: schema,
}

if proto5 == nil {
return *data, diags
}

proto5Value, err := proto5.Unmarshal(schema.Type().TerraformType(ctx))

if err != nil {
diags.AddError(
"Unable to Convert "+description.Title(),
"An unexpected error was encountered when converting the "+description.String()+" from the protocol type. "+
"This is always an issue in terraform-plugin-framework used to implement the provider and should be reported to the provider developers.\n\n"+
"Please report this to the provider developer:\n\n"+
"Unable to unmarshal DynamicValue: "+err.Error(),
)

return *data, diags
}

data.TerraformValue = proto5Value

diags.Append(data.NullifyCollectionBlocks(ctx)...)

return *data, diags
}
Loading

0 comments on commit faab4e3

Please sign in to comment.