From 092e7f5dafc089f7f2fbf68f76aac781ae87bd46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palet?= Date: Tue, 19 Sep 2023 11:21:43 +0100 Subject: [PATCH 1/6] Extend Read to compute plan name and version from plan ID --- .../services/mariadb/instance/datasource.go | 28 +++++++++++++++++++ stackit/services/mariadb/instance/resource.go | 27 ++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/stackit/services/mariadb/instance/datasource.go b/stackit/services/mariadb/instance/datasource.go index b10e35e01..ccff68510 100644 --- a/stackit/services/mariadb/instance/datasource.go +++ b/stackit/services/mariadb/instance/datasource.go @@ -3,9 +3,12 @@ package mariadb import ( "context" "fmt" + "strings" "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/terraform-provider-stackit/stackit/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/validate" @@ -174,8 +177,33 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques core.LogAndAddError(ctx, &resp.Diagnostics, "Mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + r.loadPlanNameAndVersion(ctx, &diags, &state) + // Set refreshed state diags = resp.State.Set(ctx, &state) resp.Diagnostics.Append(diags...) tflog.Info(ctx, "MariaDB instance read") } + +func (r *instanceDataSource) loadPlanNameAndVersion(ctx context.Context, diags *diag.Diagnostics, model *Model) { + projectId := model.ProjectId.ValueString() + planId := model.PlanId.ValueString() + res, err := r.client.GetOfferings(ctx, projectId).Execute() + if err != nil { + diags.AddError("Failed to list MariaDB offerings", err.Error()) + return + } + + for _, offer := range *res.Offerings { + for _, plan := range *offer.Plans { + if strings.EqualFold(*plan.Id, planId) && plan.Id != nil { + model.PlanName = types.StringPointerValue(plan.Name) + model.Version = types.StringPointerValue(offer.Version) + } + } + } + + diags.AddWarning("Could not get plan name and version for plan ID in use", "") +} diff --git a/stackit/services/mariadb/instance/resource.go b/stackit/services/mariadb/instance/resource.go index 2532868af..36e852101 100644 --- a/stackit/services/mariadb/instance/resource.go +++ b/stackit/services/mariadb/instance/resource.go @@ -291,7 +291,12 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error mapping fields", err.Error()) return + } + + // Compute and store values not present in the API response + r.loadPlanNameAndVersion(ctx, &diags, &state) + // Set refreshed state diags = resp.State.Set(ctx, state) resp.Diagnostics.Append(diags...) @@ -622,3 +627,25 @@ func (r *instanceResource) loadPlanId(ctx context.Context, diags *diag.Diagnosti } diags.AddError("Invalid plan_name", fmt.Sprintf("Couldn't find plan_name '%s' for version %s, available names are:%s", planName, version, availablePlanNames)) } + +func (r *instanceResource) loadPlanNameAndVersion(ctx context.Context, diags *diag.Diagnostics, model *Model) { + projectId := model.ProjectId.ValueString() + planId := model.PlanId.ValueString() + res, err := r.client.GetOfferings(ctx, projectId).Execute() + if err != nil { + diags.AddError("Failed to list MariaDB offerings", err.Error()) + return + } + + for _, offer := range *res.Offerings { + for _, plan := range *offer.Plans { + if strings.EqualFold(*plan.Id, planId) && plan.Id != nil { + model.PlanName = types.StringPointerValue(plan.Name) + model.Version = types.StringPointerValue(offer.Version) + return + } + } + } + + diags.AddWarning("Could not get plan name and version for plan ID in use", "") +} From a83cc17033b52fe08f035399b0df8c9e4e3ec3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palet?= Date: Tue, 19 Sep 2023 11:32:06 +0100 Subject: [PATCH 2/6] Lint --- stackit/services/mariadb/instance/resource.go | 1 - 1 file changed, 1 deletion(-) diff --git a/stackit/services/mariadb/instance/resource.go b/stackit/services/mariadb/instance/resource.go index 36e852101..f5f602529 100644 --- a/stackit/services/mariadb/instance/resource.go +++ b/stackit/services/mariadb/instance/resource.go @@ -291,7 +291,6 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r if err != nil { core.LogAndAddError(ctx, &resp.Diagnostics, "Error mapping fields", err.Error()) return - } // Compute and store values not present in the API response From 074c7f5659c7b2c376be55f71cb6e09ab6e435ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palet?= Date: Tue, 19 Sep 2023 17:25:01 +0100 Subject: [PATCH 3/6] Fix error handling; Pass client to loadPlanNameAndVersion --- .../services/mariadb/instance/datasource.go | 29 +++---------------- stackit/services/mariadb/instance/resource.go | 17 ++++++----- 2 files changed, 13 insertions(+), 33 deletions(-) diff --git a/stackit/services/mariadb/instance/datasource.go b/stackit/services/mariadb/instance/datasource.go index ccff68510..9d24b20b1 100644 --- a/stackit/services/mariadb/instance/datasource.go +++ b/stackit/services/mariadb/instance/datasource.go @@ -3,12 +3,9 @@ package mariadb import ( "context" "fmt" - "strings" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/stackitcloud/terraform-provider-stackit/stackit/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/validate" @@ -179,31 +176,13 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques } // Compute and store values not present in the API response - r.loadPlanNameAndVersion(ctx, &diags, &state) + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } // Set refreshed state diags = resp.State.Set(ctx, &state) resp.Diagnostics.Append(diags...) tflog.Info(ctx, "MariaDB instance read") } - -func (r *instanceDataSource) loadPlanNameAndVersion(ctx context.Context, diags *diag.Diagnostics, model *Model) { - projectId := model.ProjectId.ValueString() - planId := model.PlanId.ValueString() - res, err := r.client.GetOfferings(ctx, projectId).Execute() - if err != nil { - diags.AddError("Failed to list MariaDB offerings", err.Error()) - return - } - - for _, offer := range *res.Offerings { - for _, plan := range *offer.Plans { - if strings.EqualFold(*plan.Id, planId) && plan.Id != nil { - model.PlanName = types.StringPointerValue(plan.Name) - model.Version = types.StringPointerValue(offer.Version) - } - } - } - - diags.AddWarning("Could not get plan name and version for plan ID in use", "") -} diff --git a/stackit/services/mariadb/instance/resource.go b/stackit/services/mariadb/instance/resource.go index f5f602529..4e35a3f02 100644 --- a/stackit/services/mariadb/instance/resource.go +++ b/stackit/services/mariadb/instance/resource.go @@ -216,8 +216,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques ctx = tflog.SetField(ctx, "project_id", projectId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load MariaDB service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -294,7 +293,10 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r } // Compute and store values not present in the API response - r.loadPlanNameAndVersion(ctx, &diags, &state) + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } // Set refreshed state diags = resp.State.Set(ctx, state) @@ -316,8 +318,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques ctx = tflog.SetField(ctx, "instance_id", instanceId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load MariaDB service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -627,10 +628,10 @@ func (r *instanceResource) loadPlanId(ctx context.Context, diags *diag.Diagnosti diags.AddError("Invalid plan_name", fmt.Sprintf("Couldn't find plan_name '%s' for version %s, available names are:%s", planName, version, availablePlanNames)) } -func (r *instanceResource) loadPlanNameAndVersion(ctx context.Context, diags *diag.Diagnostics, model *Model) { +func loadPlanNameAndVersion(ctx context.Context, client *mariadb.APIClient, diags *diag.Diagnostics, model *Model) { projectId := model.ProjectId.ValueString() planId := model.PlanId.ValueString() - res, err := r.client.GetOfferings(ctx, projectId).Execute() + res, err := client.GetOfferings(ctx, projectId).Execute() if err != nil { diags.AddError("Failed to list MariaDB offerings", err.Error()) return @@ -646,5 +647,5 @@ func (r *instanceResource) loadPlanNameAndVersion(ctx context.Context, diags *di } } - diags.AddWarning("Could not get plan name and version for plan ID in use", "") + diags.AddError("Failed to get plan_name and version", fmt.Sprintf("Couldn't find plan_name and version for plan_id = %s", planId)) } From 44edf2ff2d85269204d3138261c012217376df75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palet?= Date: Tue, 19 Sep 2023 17:27:08 +0100 Subject: [PATCH 4/6] Change error to warning --- stackit/services/mariadb/instance/resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stackit/services/mariadb/instance/resource.go b/stackit/services/mariadb/instance/resource.go index 4e35a3f02..d2d9d63b3 100644 --- a/stackit/services/mariadb/instance/resource.go +++ b/stackit/services/mariadb/instance/resource.go @@ -647,5 +647,5 @@ func loadPlanNameAndVersion(ctx context.Context, client *mariadb.APIClient, diag } } - diags.AddError("Failed to get plan_name and version", fmt.Sprintf("Couldn't find plan_name and version for plan_id = %s", planId)) + diags.AddWarning("Failed to get plan_name and version", fmt.Sprintf("Couldn't find plan_name and version for plan_id = %s", planId)) } From 8cf9d04d50b4b2488316cac5f453f2415bc9afce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palet?= Date: Tue, 19 Sep 2023 18:01:00 +0100 Subject: [PATCH 5/6] Replicate to other DSA --- stackit/services/logme/instance/datasource.go | 7 ++++ stackit/services/logme/instance/resource.go | 35 ++++++++++++++++--- .../opensearch/instance/datasource.go | 7 ++++ .../services/opensearch/instance/resource.go | 35 ++++++++++++++++--- .../postgresql/instance/datasource.go | 7 ++++ .../services/postgresql/instance/resource.go | 35 ++++++++++++++++--- .../services/rabbitmq/instance/datasource.go | 7 ++++ .../services/rabbitmq/instance/resource.go | 35 ++++++++++++++++--- stackit/services/redis/instance/datasource.go | 7 ++++ stackit/services/redis/instance/resource.go | 35 ++++++++++++++++--- 10 files changed, 190 insertions(+), 20 deletions(-) diff --git a/stackit/services/logme/instance/datasource.go b/stackit/services/logme/instance/datasource.go index d6e15ff49..8f73c0a65 100644 --- a/stackit/services/logme/instance/datasource.go +++ b/stackit/services/logme/instance/datasource.go @@ -174,6 +174,13 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques core.LogAndAddError(ctx, &resp.Diagnostics, "Mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, &state) resp.Diagnostics.Append(diags...) diff --git a/stackit/services/logme/instance/resource.go b/stackit/services/logme/instance/resource.go index d08111163..3a51dc402 100644 --- a/stackit/services/logme/instance/resource.go +++ b/stackit/services/logme/instance/resource.go @@ -234,8 +234,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques ctx = tflog.SetField(ctx, "project_id", projectId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load LogMe service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -310,6 +309,13 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r core.LogAndAddError(ctx, &resp.Diagnostics, "Error mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, state) resp.Diagnostics.Append(diags...) @@ -330,8 +336,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques ctx = tflog.SetField(ctx, "instance_id", instanceId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load LogMe service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -641,3 +646,25 @@ func (r *instanceResource) loadPlanId(ctx context.Context, diags *diag.Diagnosti } diags.AddError("Invalid plan_name", fmt.Sprintf("Couldn't find plan_name '%s' for version %s, available names are:%s", planName, version, availablePlanNames)) } + +func loadPlanNameAndVersion(ctx context.Context, client *logme.APIClient, diags *diag.Diagnostics, model *Model) { + projectId := model.ProjectId.ValueString() + planId := model.PlanId.ValueString() + res, err := client.GetOfferings(ctx, projectId).Execute() + if err != nil { + diags.AddError("Failed to list LogMe offerings", err.Error()) + return + } + + for _, offer := range *res.Offerings { + for _, plan := range *offer.Plans { + if strings.EqualFold(*plan.Id, planId) && plan.Id != nil { + model.PlanName = types.StringPointerValue(plan.Name) + model.Version = types.StringPointerValue(offer.Version) + return + } + } + } + + diags.AddWarning("Failed to get plan_name and version", fmt.Sprintf("Couldn't find plan_name and version for plan_id = %s", planId)) +} diff --git a/stackit/services/opensearch/instance/datasource.go b/stackit/services/opensearch/instance/datasource.go index 3cce53395..6888cd8e7 100644 --- a/stackit/services/opensearch/instance/datasource.go +++ b/stackit/services/opensearch/instance/datasource.go @@ -174,6 +174,13 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques core.LogAndAddError(ctx, &resp.Diagnostics, "Mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, &state) resp.Diagnostics.Append(diags...) diff --git a/stackit/services/opensearch/instance/resource.go b/stackit/services/opensearch/instance/resource.go index 3e8932f3e..ee0a8470f 100644 --- a/stackit/services/opensearch/instance/resource.go +++ b/stackit/services/opensearch/instance/resource.go @@ -216,8 +216,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques ctx = tflog.SetField(ctx, "project_id", projectId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load OpenSearch service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -292,6 +291,13 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r core.LogAndAddError(ctx, &resp.Diagnostics, "Error mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, state) resp.Diagnostics.Append(diags...) @@ -312,8 +318,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques ctx = tflog.SetField(ctx, "instance_id", instanceId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load OpenSearch service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -621,3 +626,25 @@ func (r *instanceResource) loadPlanId(ctx context.Context, diags *diag.Diagnosti } diags.AddError("Invalid plan_name", fmt.Sprintf("Couldn't find plan_name '%s' for version %s, available names are:%s", planName, version, availablePlanNames)) } + +func loadPlanNameAndVersion(ctx context.Context, client *opensearch.APIClient, diags *diag.Diagnostics, model *Model) { + projectId := model.ProjectId.ValueString() + planId := model.PlanId.ValueString() + res, err := client.GetOfferings(ctx, projectId).Execute() + if err != nil { + diags.AddError("Failed to list OpenSearch offerings", err.Error()) + return + } + + for _, offer := range *res.Offerings { + for _, plan := range *offer.Plans { + if strings.EqualFold(*plan.Id, planId) && plan.Id != nil { + model.PlanName = types.StringPointerValue(plan.Name) + model.Version = types.StringPointerValue(offer.Version) + return + } + } + } + + diags.AddWarning("Failed to get plan_name and version", fmt.Sprintf("Couldn't find plan_name and version for plan_id = %s", planId)) +} diff --git a/stackit/services/postgresql/instance/datasource.go b/stackit/services/postgresql/instance/datasource.go index af84630f9..181813d9c 100644 --- a/stackit/services/postgresql/instance/datasource.go +++ b/stackit/services/postgresql/instance/datasource.go @@ -191,6 +191,13 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques core.LogAndAddError(ctx, &resp.Diagnostics, "Mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, &state) resp.Diagnostics.Append(diags...) diff --git a/stackit/services/postgresql/instance/resource.go b/stackit/services/postgresql/instance/resource.go index d81c0ceb7..e3b0d0c0b 100644 --- a/stackit/services/postgresql/instance/resource.go +++ b/stackit/services/postgresql/instance/resource.go @@ -261,8 +261,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques ctx = tflog.SetField(ctx, "project_id", projectId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load PostgreSQL service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -376,6 +375,13 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r core.LogAndAddError(ctx, &resp.Diagnostics, "Error mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, state) resp.Diagnostics.Append(diags...) @@ -396,8 +402,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques ctx = tflog.SetField(ctx, "instance_id", instanceId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load PostgreSQL service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -702,3 +707,25 @@ func (r *instanceResource) loadPlanId(ctx context.Context, diags *diag.Diagnosti } diags.AddError("Invalid plan_name", fmt.Sprintf("Couldn't find plan_name '%s' for version %s, available names are:%s", planName, version, availablePlanNames)) } + +func loadPlanNameAndVersion(ctx context.Context, client *postgresql.APIClient, diags *diag.Diagnostics, model *Model) { + projectId := model.ProjectId.ValueString() + planId := model.PlanId.ValueString() + res, err := client.GetOfferings(ctx, projectId).Execute() + if err != nil { + diags.AddError("Failed to list PostgreSQL offerings", err.Error()) + return + } + + for _, offer := range *res.Offerings { + for _, plan := range *offer.Plans { + if strings.EqualFold(*plan.Id, planId) && plan.Id != nil { + model.PlanName = types.StringPointerValue(plan.Name) + model.Version = types.StringPointerValue(offer.Version) + return + } + } + } + + diags.AddWarning("Failed to get plan_name and version", fmt.Sprintf("Couldn't find plan_name and version for plan_id = %s", planId)) +} diff --git a/stackit/services/rabbitmq/instance/datasource.go b/stackit/services/rabbitmq/instance/datasource.go index eaff64738..dad85ee2d 100644 --- a/stackit/services/rabbitmq/instance/datasource.go +++ b/stackit/services/rabbitmq/instance/datasource.go @@ -174,6 +174,13 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques core.LogAndAddError(ctx, &resp.Diagnostics, "Mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, &state) resp.Diagnostics.Append(diags...) diff --git a/stackit/services/rabbitmq/instance/resource.go b/stackit/services/rabbitmq/instance/resource.go index 512c7109c..0cd3b17da 100644 --- a/stackit/services/rabbitmq/instance/resource.go +++ b/stackit/services/rabbitmq/instance/resource.go @@ -229,8 +229,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques ctx = tflog.SetField(ctx, "project_id", projectId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load RabbitMQ service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -326,6 +325,13 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r core.LogAndAddError(ctx, &resp.Diagnostics, "Error mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, state) resp.Diagnostics.Append(diags...) @@ -346,8 +352,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques ctx = tflog.SetField(ctx, "instance_id", instanceId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load RabbitMQ service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -635,3 +640,25 @@ func (r *instanceResource) loadPlanId(ctx context.Context, diags *diag.Diagnosti } diags.AddError("Invalid plan_name", fmt.Sprintf("Couldn't find plan_name '%s' for version %s, available names are:%s", planName, version, availablePlanNames)) } + +func loadPlanNameAndVersion(ctx context.Context, client *rabbitmq.APIClient, diags *diag.Diagnostics, model *Model) { + projectId := model.ProjectId.ValueString() + planId := model.PlanId.ValueString() + res, err := client.GetOfferings(ctx, projectId).Execute() + if err != nil { + diags.AddError("Failed to list RabbitMQ offerings", err.Error()) + return + } + + for _, offer := range *res.Offerings { + for _, plan := range *offer.Plans { + if strings.EqualFold(*plan.Id, planId) && plan.Id != nil { + model.PlanName = types.StringPointerValue(plan.Name) + model.Version = types.StringPointerValue(offer.Version) + return + } + } + } + + diags.AddWarning("Failed to get plan_name and version", fmt.Sprintf("Couldn't find plan_name and version for plan_id = %s", planId)) +} diff --git a/stackit/services/redis/instance/datasource.go b/stackit/services/redis/instance/datasource.go index ff90fe7e3..662c5f002 100644 --- a/stackit/services/redis/instance/datasource.go +++ b/stackit/services/redis/instance/datasource.go @@ -174,6 +174,13 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques core.LogAndAddError(ctx, &resp.Diagnostics, "Mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, state) resp.Diagnostics.Append(diags...) diff --git a/stackit/services/redis/instance/resource.go b/stackit/services/redis/instance/resource.go index c779d564e..774966501 100644 --- a/stackit/services/redis/instance/resource.go +++ b/stackit/services/redis/instance/resource.go @@ -226,8 +226,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques ctx = tflog.SetField(ctx, "project_id", projectId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load Redis service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -323,6 +322,13 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r core.LogAndAddError(ctx, &resp.Diagnostics, "Error mapping fields", err.Error()) return } + + // Compute and store values not present in the API response + loadPlanNameAndVersion(ctx, r.client, &resp.Diagnostics, &state) + if resp.Diagnostics.HasError() { + return + } + // Set refreshed state diags = resp.State.Set(ctx, state) resp.Diagnostics.Append(diags...) @@ -343,8 +349,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques ctx = tflog.SetField(ctx, "instance_id", instanceId) r.loadPlanId(ctx, &resp.Diagnostics, &model) - if diags.HasError() { - core.LogAndAddError(ctx, &diags, "Failed to load Redis service plan", "plan "+model.PlanName.ValueString()) + if resp.Diagnostics.HasError() { return } @@ -632,3 +637,25 @@ func (r *instanceResource) loadPlanId(ctx context.Context, diags *diag.Diagnosti } diags.AddError("Invalid plan_name", fmt.Sprintf("Couldn't find plan_name '%s' for version %s, available names are:%s", planName, version, availablePlanNames)) } + +func loadPlanNameAndVersion(ctx context.Context, client *redis.APIClient, diags *diag.Diagnostics, model *Model) { + projectId := model.ProjectId.ValueString() + planId := model.PlanId.ValueString() + res, err := client.GetOfferings(ctx, projectId).Execute() + if err != nil { + diags.AddError("Failed to list Redis offerings", err.Error()) + return + } + + for _, offer := range *res.Offerings { + for _, plan := range *offer.Plans { + if strings.EqualFold(*plan.Id, planId) && plan.Id != nil { + model.PlanName = types.StringPointerValue(plan.Name) + model.Version = types.StringPointerValue(offer.Version) + return + } + } + } + + diags.AddWarning("Failed to get plan_name and version", fmt.Sprintf("Couldn't find plan_name and version for plan_id = %s", planId)) +} From 5f9a1fe3561f0c35da33570c011709593844325a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palet?= Date: Tue, 19 Sep 2023 18:03:39 +0100 Subject: [PATCH 6/6] Update acc tests to test import of plan name and version --- stackit/services/logme/logme_acc_test.go | 5 ++--- stackit/services/mariadb/mariadb_acc_test.go | 5 ++--- stackit/services/opensearch/opensearch_acc_test.go | 5 ++--- stackit/services/postgresql/postgresql_acc_test.go | 5 ++--- stackit/services/rabbitmq/rabbitmq_acc_test.go | 5 ++--- stackit/services/redis/redis_acc_test.go | 5 ++--- 6 files changed, 12 insertions(+), 18 deletions(-) diff --git a/stackit/services/logme/logme_acc_test.go b/stackit/services/logme/logme_acc_test.go index e3169886e..543b215d5 100644 --- a/stackit/services/logme/logme_acc_test.go +++ b/stackit/services/logme/logme_acc_test.go @@ -136,9 +136,8 @@ func TestAccLogMeResource(t *testing.T) { } return fmt.Sprintf("%s,%s", testutil.ProjectId, instanceId), nil }, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"plan_name", "version"}, + ImportState: true, + ImportStateVerify: true, }, { ResourceName: "stackit_logme_credentials.credentials", diff --git a/stackit/services/mariadb/mariadb_acc_test.go b/stackit/services/mariadb/mariadb_acc_test.go index df8477881..1e737d59d 100644 --- a/stackit/services/mariadb/mariadb_acc_test.go +++ b/stackit/services/mariadb/mariadb_acc_test.go @@ -135,9 +135,8 @@ func TestAccMariaDBResource(t *testing.T) { } return fmt.Sprintf("%s,%s", testutil.ProjectId, instanceId), nil }, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"plan_name", "version"}, + ImportState: true, + ImportStateVerify: true, }, { ResourceName: "stackit_mariadb_credentials.credentials", diff --git a/stackit/services/opensearch/opensearch_acc_test.go b/stackit/services/opensearch/opensearch_acc_test.go index 57ce148d3..071cb71fb 100644 --- a/stackit/services/opensearch/opensearch_acc_test.go +++ b/stackit/services/opensearch/opensearch_acc_test.go @@ -160,9 +160,8 @@ func TestAccOpenSearchResource(t *testing.T) { return fmt.Sprintf("%s,%s", testutil.ProjectId, instanceId), nil }, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"plan_name", "version"}, + ImportState: true, + ImportStateVerify: true, }, { ResourceName: "stackit_opensearch_credentials.credentials", diff --git a/stackit/services/postgresql/postgresql_acc_test.go b/stackit/services/postgresql/postgresql_acc_test.go index 195dddd9c..ef048a770 100644 --- a/stackit/services/postgresql/postgresql_acc_test.go +++ b/stackit/services/postgresql/postgresql_acc_test.go @@ -144,9 +144,8 @@ func TestAccPostgreSQLResource(t *testing.T) { } return fmt.Sprintf("%s,%s", testutil.ProjectId, instanceId), nil }, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"plan_name", "version"}, + ImportState: true, + ImportStateVerify: true, }, { ResourceName: "stackit_postgresql_credentials.credentials", diff --git a/stackit/services/rabbitmq/rabbitmq_acc_test.go b/stackit/services/rabbitmq/rabbitmq_acc_test.go index 5065e73f7..a804a6462 100644 --- a/stackit/services/rabbitmq/rabbitmq_acc_test.go +++ b/stackit/services/rabbitmq/rabbitmq_acc_test.go @@ -181,9 +181,8 @@ func TestAccRabbitMQResource(t *testing.T) { } return fmt.Sprintf("%s,%s", testutil.ProjectId, instanceId), nil }, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"plan_name", "version"}, + ImportState: true, + ImportStateVerify: true, }, { ResourceName: "stackit_rabbitmq_credentials.credentials", diff --git a/stackit/services/redis/redis_acc_test.go b/stackit/services/redis/redis_acc_test.go index 5ad39ca6e..81ecfe621 100644 --- a/stackit/services/redis/redis_acc_test.go +++ b/stackit/services/redis/redis_acc_test.go @@ -181,9 +181,8 @@ func TestAccRedisResource(t *testing.T) { } return fmt.Sprintf("%s,%s", testutil.ProjectId, instanceId), nil }, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"plan_name", "version"}, + ImportState: true, + ImportStateVerify: true, }, { ResourceName: "stackit_redis_credentials.credentials",