Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: tag assign project #533

Merged
merged 27 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fc1e115
feat: resource tag create
wai-wong-edb Mar 22, 2024
b06819a
fix: lint errors
wai-wong-edb Mar 22, 2024
bddbab4
fix: lint errors
wai-wong-edb Mar 22, 2024
07ba079
refactor: refactor tag client
wai-wong-edb Mar 28, 2024
714a365
feat: tag update
wai-wong-edb Mar 28, 2024
bdf1710
refactor: refactor tag client
wai-wong-edb Apr 2, 2024
086aaa7
Merge branch 'ww-tags-create' into ww-tags-update
wai-wong-edb Apr 2, 2024
cd08fe8
feat: changed tag description
wai-wong-edb Apr 2, 2024
c07f3bc
Merge branch 'ww-tags-create' into ww-tags-update
wai-wong-edb Apr 2, 2024
6a0235e
feat: tag import
wai-wong-edb Apr 2, 2024
67263ab
feat: lint error
wai-wong-edb Apr 2, 2024
e5a74f0
feat: assign tags to resources
wai-wong-edb Apr 5, 2024
7931b8b
fix: faraway replica assign tag
wai-wong-edb Apr 8, 2024
b04fa41
feat: tag in cluster examples
wai-wong-edb Apr 9, 2024
29ab369
fix: plan modifier for cluster to merge plan with state so it can dea…
wai-wong-edb Apr 9, 2024
7abe3a4
fix: cluster assign tags fix
wai-wong-edb Apr 11, 2024
496b51d
feat: pgd assign tags
wai-wong-edb Apr 11, 2024
cb47561
fix: lint fix
wai-wong-edb Apr 15, 2024
7027740
fix: examples
wai-wong-edb Apr 15, 2024
e4e58c8
feat: project tags assign
wai-wong-edb Apr 15, 2024
0364ce9
fix: planmodifier to use state so it can assign and remove correctly
wai-wong-edb Apr 15, 2024
b7dc43f
Merge branch 'main' into ww-tag-assign-pgd-project-region
wai-wong-edb Aug 14, 2024
bd4ae33
Merge branch 'main' into ww-tag-assign-pgd-project-region
wai-wong-edb Aug 19, 2024
4b97360
Merge branch 'ww-tag-assign-pgd-project-region' into ww-tag-assign-pr…
wai-wong-edb Aug 19, 2024
c165509
fix: custom plan modifier
wai-wong-edb Aug 19, 2024
a4c3abb
fix: commends on build assign tags
wai-wong-edb Sep 9, 2024
e49613e
Merge branch 'main' into ww-tag-assign-project
wai-wong-edb Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions examples/resources/biganimal_project/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ resource "random_pet" "project_name" {

resource "biganimal_project" "this" {
project_name = format("TF %s", title(random_pet.project_name.id))
#tags = [
# {
# tag_name = "ex-tag-name-1"
# color = "blue"
# },
# {
# tag_name = "ex-tag-name-2"
# },
#]
}

output "project_name" {
Expand Down
17 changes: 13 additions & 4 deletions pkg/api/project_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ func NewProjectClient(api API) *ProjectClient {
return &c
}

func (c ProjectClient) Create(ctx context.Context, projectName string) (string, error) {
func (c ProjectClient) Create(ctx context.Context, model any) (string, error) {
response := struct {
Data struct {
ProjectId string `json:"projectId"`
} `json:"data"`
}{}

project := map[string]string{"projectName": projectName}
projectRs := model.(models.Project)
project := map[string]interface{}{
"projectName": projectRs.ProjectName,
"tags": projectRs.Tags,
}

b, err := json.Marshal(project)
if err != nil {
Expand Down Expand Up @@ -83,14 +87,19 @@ func (c ProjectClient) List(ctx context.Context, query string) ([]*models.Projec
return response.Data, err
}

func (c ProjectClient) Update(ctx context.Context, projectId, projectName string) (string, error) {
func (c ProjectClient) Update(ctx context.Context, projectId, model any) (string, error) {
response := struct {
Data struct {
ProjectId string `json:"projectId"`
} `json:"data"`
}{}

project := map[string]string{"projectName": projectName}
projectRs := model.(models.Project)
project := map[string]interface{}{
"projectName": projectRs.ProjectName,
"tags": projectRs.Tags,
}

b, err := json.Marshal(project)
if err != nil {
return "", err
Expand Down
3 changes: 3 additions & 0 deletions pkg/models/project.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package models

import commonApi "github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/api"

type CloudProvider struct {
CloudProviderId string `json:"cloudProviderId,omitempty" tfsdk:"cloud_provider_id"`
CloudProviderName string `json:"cloudProviderName,omitempty" tfsdk:"cloud_provider_name"`
Expand All @@ -11,6 +13,7 @@ type Project struct {
UserCount int `json:"userCount,omitempty" tfsdk:"user_count"`
ClusterCount int `json:"clusterCount,omitempty" tfsdk:"cluster_count"`
CloudProviders []CloudProvider `json:"cloudProviders" tfsdk:"cloud_providers"`
Tags []commonApi.Tag `json:"tags,omitempty"`
}

// Check the return value, if ProjectName is also needed
Expand Down
6 changes: 3 additions & 3 deletions pkg/plan_modifier/assign_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ func (m assignTagsModifier) PlanModifySet(ctx context.Context, req planmodifier.
return
}

// This is on update and tags are not set in config so just plan for state
// Below is everything else ie update with tags set in config.

// This is on update and tags are not set in config so just use state as plan
if req.PlanValue.IsUnknown() {
resp.PlanValue = basetypes.NewSetValueMust(req.ConfigValue.ElementType(ctx), state.Elements())
return
}

// This is for anything else ie update with tags set in config.

// merge plan into newPlan (plan is from config) and merge state in newPlan (state is from read)
newPlan := state.Elements()

Expand Down
33 changes: 33 additions & 0 deletions pkg/provider/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package provider

import (
commonApi "github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/api"
commonTerraform "github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/terraform"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
)

// build tag assign terraform resource as, using api response as input
func buildTFRsrcAssignTagsAs(tfRsrcTagsOut *[]commonTerraform.Tag, apiRespTags []commonApi.Tag) {
wai-wong-edb marked this conversation as resolved.
Show resolved Hide resolved
*tfRsrcTagsOut = []commonTerraform.Tag{}
for _, v := range apiRespTags {
*tfRsrcTagsOut = append(*tfRsrcTagsOut, commonTerraform.Tag{
TagId: types.StringValue(v.TagId),
TagName: types.StringValue(v.TagName),
Color: basetypes.NewStringPointerValue(v.Color),
})
}
}

// build tag assign request using terraform resource as input
func buildAPIReqAssignTags(tfRsrcTags []commonTerraform.Tag) []commonApi.Tag {
wai-wong-edb marked this conversation as resolved.
Show resolved Hide resolved
tags := []commonApi.Tag{}
for _, tag := range tfRsrcTags {
tags = append(tags, commonApi.Tag{
Color: tag.Color.ValueStringPointer(),
TagId: tag.TagId.ValueString(),
TagName: tag.TagName.ValueString(),
})
}
return tags
}
25 changes: 1 addition & 24 deletions pkg/provider/resource_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ func readCluster(ctx context.Context, client *api.ClusterClient, tfClusterResour
}
}

buildTFRsrcAssignTagsAs(&tfClusterResource.Tags, &responseCluster.Tags)
buildTFRsrcAssignTagsAs(&tfClusterResource.Tags, responseCluster.Tags)

if responseCluster.EncryptionKeyResp != nil {
tfClusterResource.TransparentDataEncryption = &TransparentDataEncryptionModel{}
Expand Down Expand Up @@ -1221,26 +1221,3 @@ func StringSliceToSet(items *[]string) types.Set {

return types.SetValueMust(types.StringType, eles)
}

func buildTFRsrcAssignTagsAs(tfRsrcTags *[]commonTerraform.Tag, apiRespTags *[]commonApi.Tag) {
*tfRsrcTags = []commonTerraform.Tag{}
for _, v := range *apiRespTags {
*tfRsrcTags = append(*tfRsrcTags, commonTerraform.Tag{
TagId: types.StringValue(v.TagId),
TagName: types.StringValue(v.TagName),
Color: basetypes.NewStringPointerValue(v.Color),
})
}
}

func buildAPIReqAssignTags(tfRsrcTags []commonTerraform.Tag) []commonApi.Tag {
tags := []commonApi.Tag{}
for _, tag := range tfRsrcTags {
tags = append(tags, commonApi.Tag{
Color: tag.Color.ValueStringPointer(),
TagId: tag.TagId.ValueString(),
TagName: tag.TagName.ValueString(),
})
}
return tags
}
4 changes: 2 additions & 2 deletions pkg/provider/resource_pgd.go
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ func (p pgdResource) Read(ctx context.Context, req resource.ReadRequest, resp *r
state.ClusterId = clusterResp.ClusterId
state.ClusterName = clusterResp.ClusterName

buildTFRsrcAssignTagsAs(&state.Tags, &clusterResp.Tags)
buildTFRsrcAssignTagsAs(&state.Tags, clusterResp.Tags)

buildTFGroupsAs(ctx, &resp.Diagnostics, resp.State, *clusterResp, &state)
if resp.Diagnostics.HasError() {
Expand Down Expand Up @@ -1190,7 +1190,7 @@ func (p *pgdResource) retryFuncAs(ctx context.Context, diags *diag.Diagnostics,
return retry.RetryableError(errors.New("instance not yet ready"))
}

buildTFRsrcAssignTagsAs(&outPgdTfResource.Tags, &pgdResp.Tags)
buildTFRsrcAssignTagsAs(&outPgdTfResource.Tags, pgdResp.Tags)

return nil
}
Expand Down
66 changes: 58 additions & 8 deletions pkg/provider/resource_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import (
"github.com/hashicorp/terraform-plugin-framework/path"

"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/api"
"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models"
commonTerraform "github.com/EnterpriseDB/terraform-provider-biganimal/pkg/models/common/terraform"
"github.com/EnterpriseDB/terraform-provider-biganimal/pkg/plan_modifier"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
Expand Down Expand Up @@ -94,6 +97,36 @@ func (p projectResource) Schema(ctx context.Context, req resource.SchemaRequest,
},
},
},
"tags": schema.SetNestedAttribute{
Description: "Assign existing tags or create tags to assign to this resource",
Optional: true,
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"tag_id": schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"tag_name": schema.StringAttribute{
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"color": schema.StringAttribute{
Optional: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
},
},
PlanModifiers: []planmodifier.Set{
plan_modifier.CustomAssignTags(),
},
},
},
}
}
Expand All @@ -113,12 +146,13 @@ type cloudProvider struct {
}

type Project struct {
ID *string `tfsdk:"id"`
ProjectID *string `tfsdk:"project_id"`
ProjectName *string `tfsdk:"project_name"`
UserCount *int `tfsdk:"user_count"`
ClusterCount *int `tfsdk:"cluster_count"`
CloudProviders []cloudProvider `tfsdk:"cloud_providers"`
ID *string `tfsdk:"id"`
ProjectID *string `tfsdk:"project_id"`
ProjectName *string `tfsdk:"project_name"`
UserCount *int `tfsdk:"user_count"`
ClusterCount *int `tfsdk:"cluster_count"`
CloudProviders []cloudProvider `tfsdk:"cloud_providers"`
Tags []commonTerraform.Tag `tfsdk:"tags"`
}

// Create creates the resource and sets the initial Terraform state.
Expand All @@ -130,7 +164,12 @@ func (p projectResource) Create(ctx context.Context, req resource.CreateRequest,
return
}

projectId, err := p.client.Create(ctx, *config.ProjectName)
projectReqModel := models.Project{
ProjectName: *config.ProjectName,
Tags: buildAPIReqAssignTags(config.Tags),
}

projectId, err := p.client.Create(ctx, projectReqModel)
if err != nil {
resp.Diagnostics.AddError("Error creating project", "Could not create project, unexpected error: "+err.Error())
return
Expand All @@ -154,6 +193,8 @@ func (p projectResource) Create(ctx context.Context, req resource.CreateRequest,
})
}

buildTFRsrcAssignTagsAs(&config.Tags, project.Tags)

diags = resp.State.Set(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand Down Expand Up @@ -188,6 +229,8 @@ func (p projectResource) Read(ctx context.Context, req resource.ReadRequest, res
})
}

buildTFRsrcAssignTagsAs(&state.Tags, project.Tags)

diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand All @@ -204,12 +247,19 @@ func (p projectResource) Update(ctx context.Context, req resource.UpdateRequest,
return
}

_, err := p.client.Update(ctx, *plan.ProjectID, *plan.ProjectName)
projectReqModel := models.Project{
ProjectName: *plan.ProjectName,
Tags: buildAPIReqAssignTags(plan.Tags),
}

_, err := p.client.Update(ctx, *plan.ProjectID, projectReqModel)
if err != nil {
resp.Diagnostics.AddError("Error updating project", "Could not update project, unexpected error: "+err.Error())
return
}

buildTFRsrcAssignTagsAs(&plan.Tags, projectReqModel.Tags)

diags = resp.State.Set(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand Down
Loading