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

Consider Allowing Usage of Custom Types for Nested Attributes #533

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions attr/value.go
Expand Up @@ -45,4 +45,10 @@ type Value interface {
// logging and error reporting, as they are not protected by
// compatibility guarantees within the framework.
String() string

FrameworkValue
}

type FrameworkValue interface {
ToFrameworkValue() Value
}
4 changes: 3 additions & 1 deletion internal/fwschema/block.go
Expand Up @@ -2,6 +2,8 @@ package fwschema

import (
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/hashicorp/terraform-plugin-go/tftypes"
)

Expand All @@ -24,7 +26,7 @@ type Block interface {
// GetAttributes should return the nested attributes of a block, if
// applicable. This is named differently than Attributes to prevent a
// conflict with the tfsdk.Block field name.
GetAttributes() map[string]Attribute
GetAttributes() map[string]types.Attribute

// GetBlocks should return the nested blocks of a block, if
// applicable. This is named differently than Blocks to prevent a
Expand Down
4 changes: 2 additions & 2 deletions internal/fwschema/fwxschema/attribute_plan_modification.go
@@ -1,16 +1,16 @@
package fwxschema

import (
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
)

// AttributeWithPlanModifiers is an optional interface on Attribute which enables
// plan modification support.
type AttributeWithPlanModifiers interface {
// Implementations should include the fwschema.Attribute interface methods
// for proper attribute handling.
fwschema.Attribute
types.Attribute

// GetPlanModifiers should return a list of attribute-based plan modifiers.
// This is named differently than PlanModifiers to prevent a conflict with
Expand Down
4 changes: 2 additions & 2 deletions internal/fwschema/fwxschema/attribute_validation.go
@@ -1,16 +1,16 @@
package fwxschema

import (
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
)

// AttributeWithValidators is an optional interface on Attribute which enables
// validation support.
type AttributeWithValidators interface {
// Implementations should include the fwschema.Attribute interface methods
// for proper attribute handling.
fwschema.Attribute
types.Attribute

// GetValidators should return a list of attribute-based validators. This
// is named differently than PlanModifiers to prevent a conflict with the
Expand Down
8 changes: 5 additions & 3 deletions internal/fwschema/schema.go
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/types"

"github.com/hashicorp/terraform-plugin-go/tftypes"
)

Expand All @@ -18,16 +20,16 @@ type Schema interface {

// AttributeAtPath should return the Attribute at the given path or return
// an error.
AttributeAtPath(context.Context, path.Path) (Attribute, diag.Diagnostics)
AttributeAtPath(context.Context, path.Path) (types.Attribute, diag.Diagnostics)

// AttributeAtTerraformPath should return the Attribute at the given
// Terraform path or return an error.
AttributeAtTerraformPath(context.Context, *tftypes.AttributePath) (Attribute, error)
AttributeAtTerraformPath(context.Context, *tftypes.AttributePath) (types.Attribute, error)

// GetAttributes should return the attributes of a schema. This is named
// differently than Attributes to prevent a conflict with the tfsdk.Schema
// field name.
GetAttributes() map[string]Attribute
GetAttributes() map[string]types.Attribute

// GetBlocks should return the blocks of a schema. This is named
// differently than Blocks to prevent a conflict with the tfsdk.Schema
Expand Down
18 changes: 12 additions & 6 deletions internal/fwserver/attr_value.go
Expand Up @@ -3,29 +3,32 @@ package fwserver
import (
"context"

"github.com/hashicorp/terraform-plugin-go/tftypes"

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)

func coerceListValue(schemaPath path.Path, value attr.Value) (types.List, diag.Diagnostics) {
list, ok := value.(types.List)
v := value.ToFrameworkValue()

l, ok := v.(types.List)
if !ok {
return types.ListNull(nil), diag.Diagnostics{
attributePlanModificationWalkError(schemaPath, value),
}
}

return list, nil
return l, nil
}

func coerceMapValue(schemaPath path.Path, value attr.Value) (types.Map, diag.Diagnostics) {
m, ok := value.(types.Map)
v := value.ToFrameworkValue()

m, ok := v.(types.Map)
if !ok {
return types.MapNull(nil), diag.Diagnostics{
attributePlanModificationWalkError(schemaPath, value),
Expand All @@ -36,8 +39,9 @@ func coerceMapValue(schemaPath path.Path, value attr.Value) (types.Map, diag.Dia
}

func coerceObjectValue(schemaPath path.Path, value attr.Value) (types.Object, diag.Diagnostics) {
object, ok := value.(types.Object)
v := value.ToFrameworkValue()

object, ok := v.(types.Object)
if !ok {
return types.ObjectNull(nil), diag.Diagnostics{
attributePlanModificationWalkError(schemaPath, value),
Expand All @@ -48,7 +52,9 @@ func coerceObjectValue(schemaPath path.Path, value attr.Value) (types.Object, di
}

func coerceSetValue(schemaPath path.Path, value attr.Value) (types.Set, diag.Diagnostics) {
set, ok := value.(types.Set)
v := value.ToFrameworkValue()

set, ok := v.(types.Set)

if !ok {
return types.SetNull(nil), diag.Diagnostics{
Expand Down
11 changes: 5 additions & 6 deletions internal/fwserver/attribute_plan_modification.go
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata"
"github.com/hashicorp/terraform-plugin-framework/internal/logging"
Expand All @@ -29,7 +28,7 @@ type ModifyAttributePlanResponse struct {
// The extra Attribute parameter is a carry-over of creating the proto6server
// package from the tfsdk package and not wanting to export the method.
// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/365
func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) {
func AttributeModifyPlan(ctx context.Context, a types.Attribute, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) {
ctx = logging.FrameworkWithAttributePath(ctx, req.AttributePath.String())

var requiresReplace bool
Expand Down Expand Up @@ -97,7 +96,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo

nm := a.GetAttributes().GetNestingMode()
switch nm {
case fwschema.NestingModeList:
case types.NestingModeList:
configList, diags := coerceListValue(req.AttributePath, req.AttributeConfig)

resp.Diagnostics.Append(diags...)
Expand Down Expand Up @@ -219,7 +218,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
if resp.Diagnostics.HasError() {
return
}
case fwschema.NestingModeSet:
case types.NestingModeSet:
configSet, diags := coerceSetValue(req.AttributePath, req.AttributeConfig)

resp.Diagnostics.Append(diags...)
Expand Down Expand Up @@ -341,7 +340,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
if resp.Diagnostics.HasError() {
return
}
case fwschema.NestingModeMap:
case types.NestingModeMap:
configMap, diags := coerceMapValue(req.AttributePath, req.AttributeConfig)

resp.Diagnostics.Append(diags...)
Expand Down Expand Up @@ -463,7 +462,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
if resp.Diagnostics.HasError() {
return
}
case fwschema.NestingModeSingle:
case types.NestingModeSingle:
configObject, diags := coerceObjectValue(req.AttributePath, req.AttributeConfig)

resp.Diagnostics.Append(diags...)
Expand Down