How to transform terraform-plugin-framework/types package's types.Object and []types.Object to golang struct type in resource

113 Views Asked by At

I am trying to create a terraform provider. And In resource Create method I want to convert the types.Object and []types.Object (from terraform-plugin-framework/types package) to usual Golang struct so I can make a post request to my api.

This is my struct and schema

type ClusterDetails struct {
    ID             types.String `tfsdk:"id"`
    Name           types.String `tfsdk:"name"`
    CloudAccountID types.String `tfsdk:"cloud_account_id"`
    CreatedAt      types.String `tfsdk:"created_at"`
    Status         types.String `tfsdk:"status"`

    Firewall   []types.Object `tfsdk:"firewall"`
    NodeGroups types.Object   `tfsdk:"node_groups"`
}

func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        Attributes: map[string]schema.Attribute{
            "id": schema.StringAttribute{
                Computed:    true,
                Description: "ID of the cluster",
            },
            "name": schema.StringAttribute{
                Required:    true,
                Description: "Name of the cluster",
            },
            "cloud_account_id": schema.StringAttribute{
                Required:    true,
                Description: "Cloud account ID of the cluster",
            },
            "created_at": schema.StringAttribute{
                Computed:    true,
                Description: "Created at of the cluster",
            },
            "status": schema.StringAttribute{
                Computed:    true,
                Description: "Status of the cluster",
            },
            "firewall": schema.ListNestedAttribute{
                Optional: true,
                NestedObject: schema.NestedAttributeObject{
                    Attributes: map[string]schema.Attribute{
                        "type": schema.StringAttribute{
                            Optional:    true,
                            Description: "Type of the firewall rule",
                        },
                        "port": schema.Int64Attribute{
                            Optional:    true,
                            Description: "Port for the firewall rule",
                        },
                        "sources": schema.ListAttribute{
                            ElementType: types.StringType,
                            Optional:    true,
                            Description: "Sources for the firewall rule",
                        },
                    },
                },
            },
            "node_groups": schema.SingleNestedAttribute{
                Optional: true,
                Computed: true,
                Attributes: map[string]schema.Attribute{
                    "aws": schema.ListNestedAttribute{
                        Optional: true,
                        NestedObject: schema.NestedAttributeObject{
                            Attributes: map[string]schema.Attribute{
                                "region": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Region of the AWS node group",
                                },
                                "availability_zones": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                    Description: "Availability zones of the AWS node group",
                                },
                                "cidr": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "CIDR of the AWS node group",
                                },
                                "public_subnets": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                },
                                "private_subnets": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                },
                                "nodes": schema.ListNestedAttribute{
                                    Optional: true,
                                    NestedObject: schema.NestedAttributeObject{
                                        Attributes: map[string]schema.Attribute{
                                            "display_name": schema.StringAttribute{
                                                Optional:    true,
                                                Description: "Display name of the node",
                                            },
                                            "ip_address": schema.StringAttribute{
                                                Optional:    true,
                                                Description: "IP address of the node",
                                            },
                                            "is_active": schema.BoolAttribute{
                                                Optional:    true,
                                                Description: "Is the node active",
                                            },
                                        },
                                    },
                                },
                                "node_location": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Node location of the AWS node group",
                                },
                                "volume_size": schema.Int64Attribute{
                                    Optional:    true,
                                    Description: "Volume size of the AWS node group",
                                },
                                "volume_iops": schema.Int64Attribute{
                                    Optional:    true,
                                    Description: "Volume IOPS of the AWS node group",
                                },
                                "volume_type": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Volume type of the AWS node group",
                                },
                                "instance_type": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Instance type of the AWS node group",
                                },
                            },
                        },
                    },
                    "azure": schema.ListNestedAttribute{
                        Optional: true,
                        NestedObject: schema.NestedAttributeObject{
                            Attributes: map[string]schema.Attribute{
                                "region": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Region of the AWS node group",
                                },
                                "availability_zones": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                    Description: "Availability zones of the AWS node group",
                                },
                                "cidr": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "CIDR of the AWS node group",
                                },
                                "public_subnets": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                },
                                "private_subnets": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                },
                                "nodes": schema.ListNestedAttribute{
                                    Optional: true,
                                    NestedObject: schema.NestedAttributeObject{
                                        Attributes: map[string]schema.Attribute{
                                            "display_name": schema.StringAttribute{
                                                Optional:    true,
                                                Description: "Display name of the node",
                                            },
                                            "ip_address": schema.StringAttribute{
                                                Optional:    true,
                                                Description: "IP address of the node",
                                            },
                                            "is_active": schema.BoolAttribute{
                                                Optional:    true,
                                                Description: "Is the node active",
                                            },
                                        },
                                    },
                                },
                                "node_location": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Node location of the AWS node group",
                                },
                                "volume_size": schema.Int64Attribute{
                                    Optional:    true,
                                    Description: "Volume size of the AWS node group",
                                },
                                "volume_iops": schema.Int64Attribute{
                                    Optional:    true,
                                    Description: "Volume IOPS of the AWS node group",
                                },
                                "volume_type": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Volume type of the AWS node group",
                                },
                                "instance_type": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Instance type of the AWS node group",
                                },
                            },
                        },
                    },
                    "google": schema.ListNestedAttribute{
                        Optional: true,
                        NestedObject: schema.NestedAttributeObject{
                            Attributes: map[string]schema.Attribute{
                                "region": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Region of the AWS node group",
                                },
                                "availability_zones": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                    Description: "Availability zones of the AWS node group",
                                },
                                "cidr": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "CIDR of the AWS node group",
                                },
                                "public_subnets": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                },
                                "private_subnets": schema.ListAttribute{
                                    ElementType: types.StringType,
                                    Optional:    true,
                                },
                                "nodes": schema.ListNestedAttribute{
                                    Optional: true,
                                    NestedObject: schema.NestedAttributeObject{
                                        Attributes: map[string]schema.Attribute{
                                            "display_name": schema.StringAttribute{
                                                Optional:    true,
                                                Description: "Display name of the node",
                                            },
                                            "ip_address": schema.StringAttribute{
                                                Optional:    true,
                                                Description: "IP address of the node",
                                            },
                                            "is_active": schema.BoolAttribute{
                                                Optional:    true,
                                                Description: "Is the node active",
                                            },
                                        },
                                    },
                                },
                                "node_location": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Node location of the AWS node group",
                                },
                                "volume_size": schema.Int64Attribute{
                                    Optional:    true,
                                    Description: "Volume size of the AWS node group",
                                },
                                "volume_iops": schema.Int64Attribute{
                                    Optional:    true,
                                    Description: "Volume IOPS of the AWS node group",
                                },
                                "volume_type": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Volume type of the AWS node group",
                                },
                                "instance_type": schema.StringAttribute{
                                    Optional:    true,
                                    Description: "Instance type of the AWS node group",
                                },
                            },
                        },
                    },
                },
            },
        },
    }
}

This is what the responce for node_groups and firewall look like:

var (
    NodesNodeGroupType = map[string]attr.Type{
        "display_name": types.StringType,
        "ip_address":   types.StringType,
        "is_active":    types.BoolType,
    }

    NodeGroupTypes = map[string]attr.Type{
        "region": types.StringType,
        "cidr":   types.StringType,
        "availability_zones": types.ListType{
            ElemType: types.StringType,
        },
        "public_subnets": types.ListType{
            ElemType: types.StringType,
        },
        "private_subnets": types.ListType{
            ElemType: types.StringType,
        },
        "nodes": types.ListType{
            ElemType: types.ObjectType{
                AttrTypes: NodesNodeGroupType,
            },
        },
        "node_location": types.StringType,
        "volume_size":   types.Int64Type,
        "volume_iops":   types.Int64Type,
        "volume_type":   types.StringType,
        "instance_type": types.StringType,
    }

    NodeGroupsTypes = map[string]attr.Type{
        "aws": types.ListType{
            ElemType: types.ObjectType{
                AttrTypes: NodeGroupTypes,
            },
        },
        "azure": types.ListType{
            ElemType: types.ObjectType{
                AttrTypes: NodeGroupTypes,
            },
        },
        "google": types.ListType{
            ElemType: types.ObjectType{
                AttrTypes: NodeGroupTypes,
            },
        },
    }

    firewallElementsType := map[string]attr.Type{
        "type": types.StringType,
        "port": types.Float64Type,
        "sources": types.ListType{
            ElemType: types.StringType,
        },
    }
)

Now I need to use this node_groups and firewall in my api request in resources but I cant find a way to decrypt the values to Go's struct type. Heres what my structs and create method looks like:

type ClusterCreationRequestNodeGroups struct {

    // aws
    Aws []*NodeGroup `json:"aws"`

    // azure
    Azure []*NodeGroup `json:"azure"`

    // google
    Google []*NodeGroup `json:"google"`
}

type NodeGroup struct {

    // availability zones
    AvailabilityZones []string `json:"availability_zones"`

    // cidr
    Cidr string `json:"cidr,omitempty"`

    // instance type
    InstanceType string `json:"instance_type,omitempty"`

    // node location
    NodeLocation string `json:"node_location,omitempty"`

    // nodes
    Nodes []*NodeGroupNodesItems0 `json:"nodes"`

    // private subnets
    PrivateSubnets []string `json:"private_subnets"`

    // public subnets
    PublicSubnets []string `json:"public_subnets"`

    // region
    Region string `json:"region,omitempty"`

    // volume iops
    VolumeIops int64 `json:"volume_iops,omitempty"`

    // volume size
    VolumeSize int64 `json:"volume_size,omitempty"`

    // volume type
    VolumeType string `json:"volume_type,omitempty"`
}

type NodeGroupNodesItems0 struct {

    // display name
    DisplayName string `json:"display_name,omitempty"`

    // ip address
    IPAddress string `json:"ip_address,omitempty"`

    // is active
    IsActive bool `json:"is_active,omitempty"`
}

type ClusterCreationRequestFirewallRulesItems0 struct {

    // port
    Port int64 `json:"port,omitempty"`

    // sources
    Sources []string `json:"sources"`

    // type
    Type string `json:"type,omitempty"`
}

type ClusterCreationRequestFirewallRulesItems struct {

    // port
    Port int64 `json:"port,omitempty"`

    // sources
    Sources []string `json:"sources"`

    // type
    Type string `json:"type,omitempty"`
}

func (r *clusterResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
    var plan ClusterDetails
    diags := req.Plan.Get(ctx, &plan)
    resp.Diagnostics.Append(diags...)
    if resp.Diagnostics.HasError() {
        return
    }
0

There are 0 best solutions below