I use terraform-plugin-framework to develop a plugin.
I find that when i call func (c Config) Get(ctx context.Context, target interface{})
to convert data from the config. the optional config with Attributes will lead to unhandled null value
once the config is not defined, is there any why to avoid this.
here is my code
func (t clusterResourceType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{
// This description is used by the documentation generator and the language server.
MarkdownDescription: "Cluster resource",
Attributes: map[string]tfsdk.Attribute{
"project_id": {
MarkdownDescription: "The ID of the project",
Required: true,
Type: types.StringType,
},
"name": {
MarkdownDescription: "The name of the cluster",
Required: true,
Type: types.StringType,
},
"cluster_id": {
Computed: true,
MarkdownDescription: "The ID of the cluster",
PlanModifiers: tfsdk.AttributePlanModifiers{
tfsdk.UseStateForUnknown(),
},
Type: types.StringType,
},
"cluster_type": {
MarkdownDescription: "DEVELOPER: create a Developer Tier cluster \n DEDICATED:create a Dedicated Tier cluster",
Required: true,
Type: types.StringType,
},
"cloud_provider": {
MarkdownDescription: "AWS: the Amazon Web Services cloud provider \n GCP:the Google Cloud Platform cloud provider",
Required: true,
Type: types.StringType,
},
"region": {
MarkdownDescription: "the region value should match the cloud provider's region code",
Required: true,
Type: types.StringType,
},
"config": {
MarkdownDescription: "The configuration of the cluster",
Required: true,
Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
"root_password": {
Required: true,
Type: types.StringType,
},
"port": {
Optional: true,
Computed: true,
Type: types.Int64Type,
PlanModifiers: tfsdk.AttributePlanModifiers{
tfsdk.UseStateForUnknown(),
},
},
"components": {
Optional: true,
Computed: true,
PlanModifiers: tfsdk.AttributePlanModifiers{
tfsdk.UseStateForUnknown()},
Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
"tidb": {
Required: true,
Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
"node_size": {
Required: true,
Type: types.StringType,
},
"node_quantity": {
Required: true,
Type: types.Int64Type,
},
}),
},
"tikv": {
Required: true,
Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
"node_size": {
Required: true,
Type: types.StringType,
},
"storage_size_gib": {
Required: true,
Type: types.Int64Type,
},
"node_quantity": {
Required: true,
Type: types.Int64Type,
},
}),
},
"tiflash": {
Optional: true,
Attributes: tfsdk.SingleNestedAttributes(map[string]tfsdk.Attribute{
"node_size": {
Required: true,
Type: types.StringType,
},
"storage_size_gib": {
Required: true,
Type: types.Int64Type,
},
"node_quantity": {
Required: true,
Type: types.Int64Type,
},
}),
},
}),
},
"ip_access_list": {
Optional: true,
Attributes: tfsdk.ListNestedAttributes(map[string]tfsdk.Attribute{
"cidr": {
Required: true,
Type: types.StringType,
},
"description": {
Optional: true,
Type: types.StringType,
},
}),
},
}),
},
},
}, nil
}
type clusterResourceData struct {
ClusterId types.String `tfsdk:"cluster_id"`
ProjectId types.String `tfsdk:"project_id"`
Name types.String `tfsdk:"name"`
ClusterType types.String `tfsdk:"cluster_type"`
CloudProvider types.String `tfsdk:"cloud_provider"`
Region types.String `tfsdk:"region"`
Config ClusterConfig `tfsdk:"config"`
}
type ClusterConfig struct {
RootPassword string `tfsdk:"root_password"`
Port types.Int64 `tfsdk:"port"`
Components Components `tfsdk:"components"`
IPAccessList []IPAccess `tfsdk:"ip_access_list"`
}
type Components struct {
TiDB ComponentTiDB `tfsdk:"tidb"`
TiKV ComponentTiKV `tfsdk:"tikv"`
TiFlash ComponentTiFlash `tfsdk:"tiflash"`
}