Skip to content

Commit

Permalink
fix: modify plan func to validate tags for all resources
Browse files Browse the repository at this point in the history
  • Loading branch information
wai-wong-edb committed Jan 31, 2025
1 parent 2ddcd45 commit 97b1c2f
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 45 deletions.
46 changes: 46 additions & 0 deletions pkg/provider/common.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,61 @@
package provider

import (
"context"
"fmt"

"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/api"
commonApi "github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/api"
"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/terraform"
commonTerraform "github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/terraform"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
)

// validate config tags. Add error if invalid
func ValidateTags(ctx context.Context, tagClient *api.TagClient, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
set := new(types.Set)
req.Plan.GetAttribute(ctx, path.Root("tags"), set)

configTags := []terraform.Tag{}
diag := set.ElementsAs(ctx, &configTags, false)
if diag.ErrorsCount() > 0 {
resp.Diagnostics.Append(diag...)
return
}

// Validate existing tag. Existing tag colors cannot be changed in a cluster create request and must be removed.
// To change tag color, use tag request
existingTags, err := tagClient.TagClient().List(ctx)
if err != nil {
resp.Diagnostics.AddError("Error fetching existing tags", err.Error())
}
for _, configTag := range configTags {
for _, existingTag := range existingTags {
// if config tag matches existing tag, then config tags color has to match existing tag color or
// config tag color should be set to nil, other throw validation error
if existingTag.TagName == configTag.TagName.ValueString() &&
(existingTag.Color != nil && *existingTag.Color != configTag.Color.ValueString() ||
configTag.Color.ValueStringPointer() != nil) {

existingColor := "nil"
if existingTag.Color != nil {
existingColor = *existingTag.Color
}

resp.Diagnostics.AddError("An existing tag's color cannot be changed",
fmt.Sprintf("Please remove the color field for tag: `%v` or set it to the existing tag's color: `%v`.\nTo change an existing tag's color please use resource `biganimal_tag`",
configTag.TagName.ValueString(), existingColor))
}
}
}
}

// build tag assign terraform resource as, using api response as input
func buildTfRsrcTagsAs(tfRsrcTagsOut *[]commonTerraform.Tag, apiRespTags []commonApi.Tag) {
*tfRsrcTagsOut = []commonTerraform.Tag{}
Expand Down
5 changes: 5 additions & 0 deletions pkg/provider/resource_analytics_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@ func (r *analyticsClusterResource) Schema(ctx context.Context, req resource.Sche
}
}

// modify plan on at runtime
func (r *analyticsClusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
ValidateTags(ctx, r.client.TagClient(), req, resp)
}

func (r *analyticsClusterResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
// Retrieve values from plan
var config analyticsClusterResourceModel
Expand Down
47 changes: 2 additions & 45 deletions pkg/provider/resource_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/constants"
"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models"
commonApi "github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/api"
"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/terraform"
commonTerraform "github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/terraform"
"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/plan_modifier"
"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/utils"
Expand All @@ -32,7 +31,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/hashicorp/terraform-plugin-go/tftypes"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
)

Expand Down Expand Up @@ -588,50 +586,9 @@ func (c *clusterResource) Schema(ctx context.Context, req resource.SchemaRequest
}
}

// modify plan on at runtime
func (c *clusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
var planObject map[string]tftypes.Value

err := req.Plan.Raw.As(&planObject)
if err != nil {
resp.Diagnostics.AddError("Mapping plan object in cluster modify plan error", err.Error())
return
}

set := new(types.Set)
req.Plan.GetAttribute(ctx, path.Root("tags"), set)

configTags := []terraform.Tag{}
diag := set.ElementsAs(ctx, &configTags, false)
if diag.ErrorsCount() > 0 {
resp.Diagnostics.Append(diag...)
return
}

// Validate existing tag. Existing tag colors cannot be changed in a cluster create request and must be removed.
// To change tag color, use tag request
existingTags, err := c.client.TagClient().List(ctx)
if err != nil {
resp.Diagnostics.AddError("Error fetching existing tags", err.Error())
}
for _, configTag := range configTags {
for _, existingTag := range existingTags {
// if config tag matches existing tag, then config tags color has to match existing tag color or
// config tag color should be set to nil, other throw validation error
if existingTag.TagName == configTag.TagName.ValueString() &&
(existingTag.Color != nil && *existingTag.Color != configTag.Color.ValueString() ||
configTag.Color.ValueStringPointer() != nil) {

existingColor := "nil"
if existingTag.Color != nil {
existingColor = *existingTag.Color
}

resp.Diagnostics.AddError("An existing tag's color cannot be changed",
fmt.Sprintf("Please remove the color field for tag: `%v` or set it to the existing tag's color: `%v`.\nTo change an existing tag's color please use resource `biganimal_tag`",
configTag.TagName.ValueString(), existingColor))
}
}
}
ValidateTags(ctx, c.client.TagClient(), req, resp)
}

func (c *clusterResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/provider/resource_fareplica.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,11 @@ func (r *FAReplicaResource) Schema(ctx context.Context, req resource.SchemaReque
}
}

// modify plan on at runtime
func (r *FAReplicaResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
ValidateTags(ctx, r.client.TagClient(), req, resp)
}

func (r *FAReplicaResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
Expand Down
5 changes: 5 additions & 0 deletions pkg/provider/resource_pgd.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,11 @@ func PgdSchema(ctx context.Context) schema.Schema {
}
}

// modify plan on at runtime
func (p *pgdResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
ValidateTags(ctx, p.client.TagClient(), req, resp)
}

func (p pgdResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_pgd"
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/provider/resource_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ func (p projectResource) Schema(ctx context.Context, req resource.SchemaRequest,
}
}

// modify plan on at runtime
func (p *projectResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
ValidateTags(ctx, p.client.TagClient(), req, resp)
}

// Configure adds the provider configured client to the data source.
func (p *projectResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
if req.ProviderData == nil {
Expand Down
5 changes: 5 additions & 0 deletions pkg/provider/resource_region.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ func (r regionResource) Schema(ctx context.Context, req resource.SchemaRequest,
}
}

// modify plan on at runtime
func (r *regionResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
ValidateTags(ctx, r.client.TagClient(), req, resp)
}

func (r *regionResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
Expand Down

0 comments on commit 97b1c2f

Please sign in to comment.