Skip to content

Commit

Permalink
Merge pull request #2141 from okta/OKTA-831117
Browse files Browse the repository at this point in the history
add support to get user_type by id
  • Loading branch information
duytiennguyen-okta authored Nov 20, 2024
2 parents 92a7b86 + f610cd0 commit d34029e
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 36 deletions.
9 changes: 9 additions & 0 deletions examples/data-sources/okta_user_type/read_id.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resource "okta_user_type" "test" {
name = "testAcc_replace_with_uuid"
display_name = "Terraform Acceptance Test User Type"
description = "Terraform Acceptance Test User Type"
}

data "okta_user_type" "test2" {
id = okta_user_type.test.id
}
120 changes: 90 additions & 30 deletions okta/data_source_okta_user_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,115 @@ package okta

import (
"context"
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/okta/terraform-provider-okta/sdk"
)

func dataSourceUserType() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceUserTypeRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of user type to retrieve.",
type userTypeModel struct {
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
DisplayName types.String `tfsdk:"display_name"`
Description types.String `tfsdk:"description"`
}

func NewUserTypeDataSource() datasource.DataSource {
return &userTypeDataSource{}
}

type userTypeDataSource struct {
config *Config
}

func (d *userTypeDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_user_type"
}

func (d *userTypeDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Get a user type from Okta.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "ID of the user type to retrieve, conflicts with `name`.",
Optional: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(path.Expressions{
path.MatchRoot("name"),
}...),
},
},
"display_name": {
Type: schema.TypeString,
Computed: true,
Description: "Display name of user type.",
"name": schema.StringAttribute{
Description: "Name of user type to retrieve, conflicts with `id`.",
Optional: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(path.Expressions{
path.MatchRoot("id"),
}...),
},
},
"description": {
Type: schema.TypeString,
"display_name": schema.StringAttribute{
Description: "Display name of user type.",
Computed: true,
},
"description": schema.StringAttribute{
Description: "Description of user type.",
Computed: true,
},
},
Description: "Get a user type from Okta.",
}
}

func dataSourceUserTypeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
userTypes, _, err := getOktaClientFromMetadata(m).UserType.ListUserTypes(ctx)
func (d *userTypeDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
d.config = dataSourceConfiguration(req, resp)
}

func (d *userTypeDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var err error
var data userTypeModel
resp.Diagnostics.Append(resp.State.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
var userTypeResp *sdk.UserType
if data.ID.ValueString() != "" {
userTypeResp, _, err = d.config.oktaSDKClientV2.UserType.GetUserType(ctx, data.ID.ValueString())
} else {
userTypeResp, err = findUserTypeByName(ctx, d.config.oktaSDKClientV2, data.Name.ValueString())
}
if err != nil {
return diag.Errorf("failed to list user types: %v", err)
resp.Diagnostics.AddError(
"failed to get user type",
err.Error(),
)
return
}
name := d.Get("name").(string)

data.ID = types.StringValue(userTypeResp.Id)
data.Name = types.StringValue(userTypeResp.Name)
data.DisplayName = types.StringValue(userTypeResp.DisplayName)
data.Description = types.StringValue(userTypeResp.Description)

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

func findUserTypeByName(ctx context.Context, client *sdk.Client, name string) (*sdk.UserType, error) {
var userType *sdk.UserType
for _, ut := range userTypes {
userTypeListResp, _, err := client.UserType.ListUserTypes(ctx)
if err != nil {
return nil, err
}
for _, ut := range userTypeListResp {
if strings.EqualFold(name, ut.Name) {
userType = ut
return userType, nil
}
}
if userType == nil {
return diag.Errorf("user type '%s' does not exist", name)
}
d.SetId(userType.Id)
_ = d.Set("display_name", userType.DisplayName)
_ = d.Set("description", userType.Description)

return nil
return nil, fmt.Errorf("user type '%s' does not exist", name)
}
17 changes: 12 additions & 5 deletions okta/data_source_okta_user_type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ func TestAccDataSourceOktaUserType_read(t *testing.T) {
resourceName := fmt.Sprintf("data.%s.test", userType)
mgr := newFixtureManager("data-sources", userType, t.Name())
createUserType := mgr.GetFixtures("okta_user_type.tf", t)
config := mgr.GetFixtures("datasource.tf", t)
readNameConfig := mgr.GetFixtures("read_name.tf", t)
readIdConfig := mgr.GetFixtures("read_id.tf", t)

oktaResourceTest(t, resource.TestCase{
PreCheck: testAccPreCheck(t),
ErrorCheck: testAccErrorChecks(t),
ProviderFactories: testAccProvidersFactories,
PreCheck: testAccPreCheck(t),
ErrorCheck: testAccErrorChecks(t),
ProtoV5ProviderFactories: testAccMergeProvidersFactories,
Steps: []resource.TestStep{
{
Config: createUserType,
Expand All @@ -25,11 +26,17 @@ func TestAccDataSourceOktaUserType_read(t *testing.T) {
),
},
{
Config: config,
Config: readNameConfig,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(resourceName, "id"),
),
},
{
Config: readIdConfig,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(fmt.Sprintf("data.%s.test2", userType), "name"),
),
},
},
})
}
1 change: 1 addition & 0 deletions okta/framework_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ func (p *FrameworkProvider) DataSources(_ context.Context) []func() datasource.D
NewDefaultSigninPageDataSource,
NewLogStreamDataSource,
NewAppsDataSource,
NewUserTypeDataSource,
}
}

Expand Down
1 change: 0 additions & 1 deletion okta/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ func Provider() *schema.Provider {
userProfileMappingSource: dataSourceUserProfileMappingSource(),
users: dataSourceUsers(),
userSecurityQuestions: dataSourceUserSecurityQuestions(),
userType: dataSourceUserType(),
},
ConfigureContextFunc: providerConfigure,
}
Expand Down

0 comments on commit d34029e

Please sign in to comment.