Skip to content

Commit

Permalink
Merge pull request #325 from csquire/migrate-license-map-resource
Browse files Browse the repository at this point in the history
chore: Migrate license map resource from SDKv2 to plugin framework
  • Loading branch information
chasewalden authored Dec 19, 2024
2 parents 3a7df3d + 81711d2 commit 8c2938c
Show file tree
Hide file tree
Showing 12 changed files with 315 additions and 181 deletions.
6 changes: 3 additions & 3 deletions docs/resources/license_map.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
page_title: "dbtcloud_license_map Resource - dbtcloud"
subcategory: ""
description: |-
Maps SSO groups to a given license type
---

# dbtcloud_license_map (Resource)



Maps SSO groups to a given license type

## Example Usage

Expand Down Expand Up @@ -45,7 +45,7 @@ resource "dbtcloud_license_map" "it_license_map" {

### Read-Only

- `id` (String) The ID of this resource.
- `id` (Number) The ID of the license map

## Import

Expand Down
3 changes: 1 addition & 2 deletions pkg/framework/objects/group/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package group

import (
"context"
"fmt"
"strconv"
"strings"

Expand Down Expand Up @@ -263,7 +262,7 @@ func (r *groupResource) ImportState(
groupIDStr := req.ID
groupID, err := strconv.Atoi(groupIDStr)
if err != nil {
fmt.Println(err)
resp.Diagnostics.AddError("Error parsing group ID for import", err.Error())
return
}

Expand Down
11 changes: 11 additions & 0 deletions pkg/framework/objects/license_map/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package license_map

import (
"github.com/hashicorp/terraform-plugin-framework/types"
)

type LicenseMapResourceModel struct {
ID types.Int64 `tfsdk:"id"`
LicenseType types.String `tfsdk:"license_type"`
SSOLicenseMappingGroups types.Set `tfsdk:"sso_license_mapping_groups"`
}
240 changes: 240 additions & 0 deletions pkg/framework/objects/license_map/resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
package license_map

import (
"context"
"github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud"
"github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/samber/lo"
"strconv"
"strings"
)

var (
_ resource.Resource = &licenseMapResource{}
_ resource.ResourceWithConfigure = &licenseMapResource{}

licenseTypes = []string{
"developer",
"read_only",
"it",
}
)

func LicenseMapResource() resource.Resource {
return &licenseMapResource{}
}

type licenseMapResource struct {
client *dbt_cloud.Client
}

func (r *licenseMapResource) Metadata(
_ context.Context,
req resource.MetadataRequest,
resp *resource.MetadataResponse,
) {
resp.TypeName = req.ProviderTypeName + "_license_map"
}

func (r *licenseMapResource) Read(
ctx context.Context,
req resource.ReadRequest,
resp *resource.ReadResponse,
) {
var state LicenseMapResourceModel

resp.Diagnostics.Append(req.State.Get(ctx, &state)...)

licenseMapID := state.ID.ValueInt64()
licenseMap, err := r.client.GetLicenseMap(int(licenseMapID))
if err != nil {
if strings.HasPrefix(err.Error(), "resource-not-found") {
resp.Diagnostics.AddWarning(
"Resource not found",
"The license map resource was not found and has been removed from the state.",
)
resp.State.RemoveResource(ctx)
return
}
resp.Diagnostics.AddError("Error getting the license map", err.Error())
return
}

state.ID = types.Int64Value(int64(*licenseMap.ID))
state.LicenseType = types.StringValue(licenseMap.LicenseType)
state.SSOLicenseMappingGroups, _ = types.SetValueFrom(
context.Background(),
types.StringType,
licenseMap.SSOLicenseMappingGroups,
)

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

func (r *licenseMapResource) Create(
ctx context.Context,
req resource.CreateRequest,
resp *resource.CreateResponse,
) {
var plan LicenseMapResourceModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

var configSsoMapping []string
diags := plan.SSOLicenseMappingGroups.ElementsAs(
context.Background(),
&configSsoMapping,
false,
)
if diags.HasError() {
resp.Diagnostics.AddError("Error extracting the list of SSO groups", "")
return
}

licenseMap, err := r.client.CreateLicenseMap(
plan.LicenseType.ValueString(),
configSsoMapping,
)

if err != nil {
resp.Diagnostics.AddError(
"Unable to create license map",
"Error: "+err.Error(),
)
return
}

plan.ID = types.Int64PointerValue(helper.IntPointerToInt64Pointer(licenseMap.ID))
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}

func (r *licenseMapResource) Delete(
ctx context.Context,
req resource.DeleteRequest,
resp *resource.DeleteResponse,
) {
var state LicenseMapResourceModel

resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

licenseMapID := int(state.ID.ValueInt64())

err := r.client.DestroyLicenseMap(licenseMapID)
if err != nil {
resp.Diagnostics.AddError("Error deleting the license map", err.Error())
return
}
}

func (r *licenseMapResource) Update(
ctx context.Context,
req resource.UpdateRequest,
resp *resource.UpdateResponse,
) {
var plan, state LicenseMapResourceModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

licenseMapID := int(state.ID.ValueInt64())
licenseMap, err := r.client.GetLicenseMap(licenseMapID)
if err != nil {
resp.Diagnostics.AddError(
"Error getting the license map",
"Error: "+err.Error(),
)
return
}

var planSsoMapping []string
diags := plan.SSOLicenseMappingGroups.ElementsAs(
context.Background(),
&planSsoMapping,
false,
)
if diags.HasError() {
resp.Diagnostics.AddError("Error extracting the list of SSO groups from the plan", "")
return
}

var stateSsoMapping []string
diags = state.SSOLicenseMappingGroups.ElementsAs(
context.Background(),
&stateSsoMapping,
false,
)
if diags.HasError() {
resp.Diagnostics.AddError("Error extracting the list of SSO groups from the state", "")
return
}

deletedSsoMapping, newSsoMapping := lo.Difference(stateSsoMapping, planSsoMapping)
hasMappingChanges := len(deletedSsoMapping) > 0 || len(newSsoMapping) > 0

if state.LicenseType != plan.LicenseType || hasMappingChanges {
if state.LicenseType != plan.LicenseType {
licenseMap.LicenseType = plan.LicenseType.ValueString()
}

if hasMappingChanges {
licenseMap.SSOLicenseMappingGroups = planSsoMapping
}

_, err = r.client.UpdateLicenseMap(licenseMapID, *licenseMap)
if err != nil {
resp.Diagnostics.AddError(
"Unable to update the existing license map",
"Error: "+err.Error(),
)
return
}
}

resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}

func (r *licenseMapResource) ImportState(
ctx context.Context,
req resource.ImportStateRequest,
resp *resource.ImportStateResponse,
) {
licenseMapID, err := strconv.Atoi(req.ID)
if err != nil {
resp.Diagnostics.AddError("Error parsing license map ID for import", err.Error())
return
}
ssoLicenseMappingGroups, _ := types.SetValue(types.StringType, nil)
state := LicenseMapResourceModel{
ID: types.Int64Value(int64(licenseMapID)),
SSOLicenseMappingGroups: ssoLicenseMappingGroups,
}

diags := resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}

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

r.client = req.ProviderData.(*dbt_cloud.Client)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package resources_test
package license_map_test

import (
"fmt"
Expand All @@ -18,7 +18,7 @@ func TestAccDbtCloudLicenseMapResource(t *testing.T) {
groupName2 := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
PreCheck: func() { acctest_helper.TestAccPreCheck(t) },
ProtoV6ProviderFactories: acctest_helper.TestAccProtoV6ProviderFactories,
CheckDestroy: testAccCheckDbtCloudLicenseMapDestroy,
Steps: []resource.TestStep{
Expand Down
46 changes: 46 additions & 0 deletions pkg/framework/objects/license_map/schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package license_map

import (
"context"
"github.com/dbt-labs/terraform-provider-dbtcloud/pkg/helper"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource"
"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"
)

func (r *licenseMapResource) Schema(
_ context.Context,
_ resource.SchemaRequest,
resp *resource.SchemaResponse,
) {
resp.Schema = schema.Schema{
Description: helper.DocString(
`Maps SSO groups to a given license type`,
),
Attributes: map[string]schema.Attribute{
"id": schema.Int64Attribute{
Computed: true,
Description: "The ID of the license map",
PlanModifiers: []planmodifier.Int64{
int64planmodifier.UseStateForUnknown(),
},
},
"license_type": schema.StringAttribute{
Required: true,
Description: "License type",
Validators: []validator.String{
stringvalidator.OneOf(licenseTypes...),
},
},
"sso_license_mapping_groups": schema.SetAttribute{
Optional: true,
Description: "SSO license mapping group names for this group",
ElementType: types.StringType,
},
},
}
}
3 changes: 1 addition & 2 deletions pkg/framework/objects/oauth_configuration/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package oauth_configuration

import (
"context"
"fmt"
"strconv"
"strings"

Expand Down Expand Up @@ -267,7 +266,7 @@ func (r *oAuthConfigurationResource) ImportState(
oAuthConfigurationIDStr := req.ID
oAuthConfigurationID, err := strconv.Atoi(oAuthConfigurationIDStr)
if err != nil {
fmt.Println(err)
resp.Diagnostics.AddError("Error parsing OAuth configuration ID for import", err.Error())
return
}

Expand Down
10 changes: 2 additions & 8 deletions pkg/framework/objects/partial_license_map/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,12 @@ package partial_license_map

import (
"github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud"
"github.com/dbt-labs/terraform-provider-dbtcloud/pkg/framework/objects/license_map"
"github.com/hashicorp/terraform-plugin-framework/types"
)

// TODO: Move the model to the non partial when moved to the Framework
type LicenseMapResourceModel struct {
ID types.Int64 `tfsdk:"id"`
LicenseType types.String `tfsdk:"license_type"`
SSOLicenseMappingGroups types.Set `tfsdk:"sso_license_mapping_groups"`
}

func matchPartial(
licenseMapModel LicenseMapResourceModel,
licenseMapModel license_map.LicenseMapResourceModel,
licenseTypeResponse dbt_cloud.LicenseMap,
) bool {
return licenseMapModel.LicenseType == types.StringValue(licenseTypeResponse.LicenseType)
Expand Down
Loading

0 comments on commit 8c2938c

Please sign in to comment.