feat: enhance database resource model with project, region, and instance attributes
This commit is contained in:
parent
e2f7370849
commit
a46e26b69b
1 changed files with 112 additions and 34 deletions
|
|
@ -14,9 +14,6 @@ import (
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||||
|
|
@ -25,24 +22,33 @@ import (
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
postgresflexalpha2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/database/resources_gen"
|
postgresflexalpha2 "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/database/resources_gen"
|
||||||
postgresflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/utils"
|
postgresflexUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/utils"
|
||||||
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure the implementation satisfies the expected interfaces.
|
|
||||||
var (
|
var (
|
||||||
|
// Ensure the implementation satisfies the expected interfaces.
|
||||||
_ resource.Resource = &databaseResource{}
|
_ resource.Resource = &databaseResource{}
|
||||||
_ resource.ResourceWithConfigure = &databaseResource{}
|
_ resource.ResourceWithConfigure = &databaseResource{}
|
||||||
_ resource.ResourceWithImportState = &databaseResource{}
|
_ resource.ResourceWithImportState = &databaseResource{}
|
||||||
_ resource.ResourceWithModifyPlan = &databaseResource{}
|
_ resource.ResourceWithModifyPlan = &databaseResource{}
|
||||||
_ resource.ResourceWithIdentity = &databaseResource{}
|
_ resource.ResourceWithIdentity = &databaseResource{}
|
||||||
|
|
||||||
|
// Define errors
|
||||||
errDatabaseNotFound = errors.New("database not found")
|
errDatabaseNotFound = errors.New("database not found")
|
||||||
|
|
||||||
|
// Error message constants
|
||||||
|
extractErrorSummary = "extracting failed"
|
||||||
|
extractErrorMessage = "Extracting identity data: %v"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResourceModel describes the resource data model.
|
// ResourceModel describes the resource data model.
|
||||||
type ResourceModel struct {
|
type ResourceModel struct {
|
||||||
postgresflexalpha2.DatabaseModel
|
postgresflexalpha2.DatabaseModel
|
||||||
TerraformID types.String `tfsdk:"id"`
|
ProjectID types.String `tfsdk:"project_id"`
|
||||||
|
Region types.String `tfsdk:"region"`
|
||||||
|
InstanceID types.String `tfsdk:"instance_id"`
|
||||||
DatabaseID types.Int64 `tfsdk:"database_id"`
|
DatabaseID types.Int64 `tfsdk:"database_id"`
|
||||||
|
TerraformID types.String `tfsdk:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DatabaseResourceIdentityModel describes the resource's identity attributes.
|
// DatabaseResourceIdentityModel describes the resource's identity attributes.
|
||||||
|
|
@ -86,7 +92,7 @@ func (r *databaseResource) ModifyPlan(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO utils.AdaptRegion(ctx, configModel.Region, &planModel.Region, r.providerData.GetRegion(), resp)
|
utils.AdaptRegion(ctx, configModel.Region, &planModel.Region, r.providerData.GetRegion(), resp)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -128,19 +134,33 @@ var modifiersFileByte []byte
|
||||||
// Schema defines the schema for the resource.
|
// Schema defines the schema for the resource.
|
||||||
func (r *databaseResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
func (r *databaseResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||||
s := postgresflexalpha2.DatabaseResourceSchema(ctx)
|
s := postgresflexalpha2.DatabaseResourceSchema(ctx)
|
||||||
|
|
||||||
|
s.Attributes["project_id"] = schema.StringAttribute{
|
||||||
|
Description: "STACKIT project ID to which the instance is associated.",
|
||||||
|
MarkdownDescription: "STACKIT project ID to which the instance is associated.",
|
||||||
|
Required: true,
|
||||||
|
}
|
||||||
|
s.Attributes["instance_id"] = schema.StringAttribute{
|
||||||
|
Description: "ID of the PostgresFlex instance.",
|
||||||
|
MarkdownDescription: "ID of the PostgresFlex instance.",
|
||||||
|
Required: true,
|
||||||
|
}
|
||||||
|
s.Attributes["region"] = schema.StringAttribute{
|
||||||
|
Description: "Region of the PostgresFlex instance.",
|
||||||
|
MarkdownDescription: "Region of the PostgresFlex instance.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
}
|
||||||
|
s.Attributes["database_id"] = schema.Int64Attribute{
|
||||||
|
Description: "The ID of the database.",
|
||||||
|
Computed: true,
|
||||||
|
}
|
||||||
|
|
||||||
s.Attributes["id"] = schema.StringAttribute{
|
s.Attributes["id"] = schema.StringAttribute{
|
||||||
Description: "Terraform's internal resource ID. It is structured as \\\"`project_id`,`region`,`instance_id`,`database_id`\\\".\",",
|
Description: "Terraform's internal resource ID. It is structured as \\\"`project_id`,`region`,`instance_id`,`database_id`\\\".\",",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
}
|
}
|
||||||
s.Attributes["database_id"] = schema.Int64Attribute{
|
|
||||||
Description: "ID of the database.",
|
|
||||||
Computed: true,
|
|
||||||
PlanModifiers: []planmodifier.Int64{
|
|
||||||
int64planmodifier.UseStateForUnknown(),
|
|
||||||
},
|
|
||||||
Validators: []validator.Int64{},
|
|
||||||
}
|
|
||||||
|
|
||||||
fields, err := postgresflexUtils.ReadModifiersConfig(modifiersFileByte)
|
fields, err := postgresflexUtils.ReadModifiersConfig(modifiersFileByte)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -300,10 +320,16 @@ func (r *databaseResource) Read(
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := identityData.ProjectID.ValueString()
|
projectId, instanceId, region, databaseId, errExt := r.extractIdentityData(model, identityData)
|
||||||
instanceId := identityData.InstanceID.ValueString()
|
if errExt != nil {
|
||||||
databaseId := model.DatabaseID.ValueInt64()
|
core.LogAndAddError(
|
||||||
region := r.providerData.GetRegionWithOverride(identityData.Region)
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
extractErrorSummary,
|
||||||
|
fmt.Sprintf(extractErrorMessage, errExt),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
@ -365,11 +391,16 @@ func (r *databaseResource) Update(
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := identityData.ProjectID.ValueString()
|
projectId, instanceId, region, databaseId64, errExt := r.extractIdentityData(model, identityData)
|
||||||
instanceId := identityData.InstanceID.ValueString()
|
if errExt != nil {
|
||||||
region := r.providerData.GetRegionWithOverride(identityData.Region)
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
extractErrorSummary,
|
||||||
|
fmt.Sprintf(extractErrorMessage, errExt),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
databaseId64 := model.DatabaseID.ValueInt64() // database id
|
|
||||||
if databaseId64 > math.MaxInt32 {
|
if databaseId64 > math.MaxInt32 {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error in type conversion", "int value too large (databaseId)")
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error in type conversion", "int value too large (databaseId)")
|
||||||
return
|
return
|
||||||
|
|
@ -463,10 +494,15 @@ func (r *databaseResource) Delete(
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := identityData.ProjectID.ValueString()
|
projectId, instanceId, region, databaseId64, errExt := r.extractIdentityData(model, identityData)
|
||||||
instanceId := identityData.InstanceID.ValueString()
|
if errExt != nil {
|
||||||
region := r.providerData.GetRegionWithOverride(identityData.Region)
|
core.LogAndAddError(
|
||||||
databaseId64 := model.DatabaseID.ValueInt64() //database id
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
extractErrorSummary,
|
||||||
|
fmt.Sprintf(extractErrorMessage, errExt),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if databaseId64 > math.MaxInt32 {
|
if databaseId64 > math.MaxInt32 {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error in type conversion", "int value too large (databaseId)")
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error in type conversion", "int value too large (databaseId)")
|
||||||
|
|
@ -525,13 +561,12 @@ func (r *databaseResource) ImportState(
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_id"), databaseId)...)
|
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_id"), databaseId)...)
|
||||||
|
|
||||||
//TODO: Investigate if this logic is still required.
|
core.LogAndAddWarning(
|
||||||
//core.LogAndAddWarning(
|
ctx,
|
||||||
// ctx,
|
&resp.Diagnostics,
|
||||||
// &resp.Diagnostics,
|
"Postgresflex database imported with empty password",
|
||||||
// "Postgresflex database imported with empty password",
|
"The database password is not imported as it is only available upon creation of a new database. The password field will be empty.",
|
||||||
// "The database password is not imported as it is only available upon creation of a new database. The password field will be empty.",
|
)
|
||||||
//)
|
|
||||||
|
|
||||||
var identityData DatabaseResourceIdentityModel
|
var identityData DatabaseResourceIdentityModel
|
||||||
identityData.ProjectID = types.StringValue(idParts[0])
|
identityData.ProjectID = types.StringValue(idParts[0])
|
||||||
|
|
@ -539,7 +574,7 @@ func (r *databaseResource) ImportState(
|
||||||
identityData.InstanceID = types.StringValue(idParts[2])
|
identityData.InstanceID = types.StringValue(idParts[2])
|
||||||
identityData.DatabaseID = types.Int64Value(databaseId)
|
identityData.DatabaseID = types.Int64Value(databaseId)
|
||||||
|
|
||||||
resp.Diagnostics.Append(req.Identity.Set(ctx, &identityData)...)
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, &identityData)...)
|
||||||
|
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
|
|
@ -548,3 +583,46 @@ func (r *databaseResource) ImportState(
|
||||||
tflog.Info(ctx, "Postgres Flex instance state imported")
|
tflog.Info(ctx, "Postgres Flex instance state imported")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model.
|
||||||
|
func (r *databaseResource) extractIdentityData(
|
||||||
|
model ResourceModel,
|
||||||
|
identity DatabaseResourceIdentityModel,
|
||||||
|
) (projectId, region, instanceId string, databaseId int64, err error) {
|
||||||
|
if !model.DatabaseID.IsNull() && !model.DatabaseID.IsUnknown() {
|
||||||
|
databaseId = model.DatabaseID.ValueInt64()
|
||||||
|
} else {
|
||||||
|
if identity.DatabaseID.IsNull() || identity.DatabaseID.IsUnknown() {
|
||||||
|
return "", "", "", 0, fmt.Errorf("database_id not found in config")
|
||||||
|
}
|
||||||
|
databaseId = identity.DatabaseID.ValueInt64()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !model.ProjectID.IsNull() && !model.ProjectID.IsUnknown() {
|
||||||
|
projectId = model.ProjectID.ValueString()
|
||||||
|
} else {
|
||||||
|
if identity.ProjectID.IsNull() || identity.ProjectID.IsUnknown() {
|
||||||
|
return "", "", "", 0, fmt.Errorf("project_id not found in config")
|
||||||
|
}
|
||||||
|
projectId = identity.ProjectID.ValueString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !model.Region.IsNull() && !model.Region.IsUnknown() {
|
||||||
|
region = r.providerData.GetRegionWithOverride(model.Region)
|
||||||
|
} else {
|
||||||
|
if identity.Region.IsNull() || identity.Region.IsUnknown() {
|
||||||
|
return "", "", "", 0, fmt.Errorf("region not found in config")
|
||||||
|
}
|
||||||
|
region = r.providerData.GetRegionWithOverride(identity.Region)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !model.InstanceID.IsNull() && !model.InstanceID.IsUnknown() {
|
||||||
|
instanceId = model.InstanceID.ValueString()
|
||||||
|
} else {
|
||||||
|
if identity.InstanceID.IsNull() || identity.InstanceID.IsUnknown() {
|
||||||
|
return "", "", "", 0, fmt.Errorf("instance_id not found in config")
|
||||||
|
}
|
||||||
|
instanceId = identity.InstanceID.ValueString()
|
||||||
|
}
|
||||||
|
return projectId, region, instanceId, databaseId, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue