Skip to content

Commit

Permalink
Fixed user type by introducing state upgrader (#242)
Browse files Browse the repository at this point in the history
* Fixed user type by introducing state upgrader
  • Loading branch information
bogdanprodan-okta authored Dec 16, 2020
1 parent 73cf51b commit f1f1cb7
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 53 deletions.
2 changes: 1 addition & 1 deletion okta/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (c *Config) loadAndValidate() error {
okta.WithHttpClient(*httpClient),
okta.WithRateLimitMaxBackOff(int64(c.maxWait)),
okta.WithRateLimitMaxRetries(int32(c.retryCount)),
okta.WithUserAgentExtra("okta-terraform/3.6.0"),
okta.WithUserAgentExtra("okta-terraform/3.7.1"),
)
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions okta/provider_sweeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestMain(m *testing.M) {
setupSweeper(userBaseSchema, sweepUserBaseSchema)
setupSweeper(networkZone, sweepNetworkZones)
setupSweeper(inlineHook, sweepInlineHooks)
setupSweeper(userType, sweepUserTypes)

// add zones sweeper
resource.TestMain(m)
Expand Down
20 changes: 20 additions & 0 deletions okta/resource_okta_app_user_base_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,29 @@ func resourceAppUserBaseSchema() *schema.Resource {
Required: true,
},
}),
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceAppUserBaseSchemaResourceV0().CoreConfigSchema().ImpliedType(),
Upgrade: func(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
rawState["user_type"] = "default"
return rawState, nil
},
Version: 0,
},
},
}
}

func resourceAppUserBaseSchemaResourceV0() *schema.Resource {
return &schema.Resource{Schema: buildSchema(map[string]*schema.Schema{
"app_id": {
Type: schema.TypeString,
Required: true,
},
}, userBaseSchemaSchema)}
}

func resourceAppUserBaseSchemaCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
if err := updateAppUserBaseSubschema(ctx, d, m); err != nil {
return err
Expand Down
20 changes: 20 additions & 0 deletions okta/resource_okta_app_user_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,29 @@ func resourceAppUserSchema() *schema.Resource {
Required: true,
},
}),
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceAppUserSchemaResourceV0().CoreConfigSchema().ImpliedType(),
Upgrade: func(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
rawState["user_type"] = "default"
return rawState, nil
},
Version: 0,
},
},
}
}

func resourceAppUserSchemaResourceV0() *schema.Resource {
return &schema.Resource{Schema: buildSchema(map[string]*schema.Schema{
"app_id": {
Type: schema.TypeString,
Required: true,
},
}, userSchemaSchema, userBaseSchemaSchema)}
}

func resourceAppUserSchemaCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
if err := updateAppUserSubschema(ctx, d, m); err != nil {
return err
Expand Down
17 changes: 16 additions & 1 deletion okta/resource_okta_user_base_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,25 @@ func resourceUserBaseSchema() *schema.Resource {
return []*schema.ResourceData{d}, nil
},
},
Schema: userBaseSchemaSchema,
SchemaVersion: 1,
Schema: buildSchema(userBaseSchemaSchema, userTypeSchema),
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceUserBaseSchemaResourceV0().CoreConfigSchema().ImpliedType(),
Upgrade: func(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
rawState["user_type"] = "default"
return rawState, nil
},
Version: 0,
},
},
}
}

func resourceUserBaseSchemaResourceV0() *schema.Resource {
return &schema.Resource{Schema: userBaseSchemaSchema}
}

func resourceUserBaseSchemaCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
schemaUrl, err := getUserTypeSchemaUrl(ctx, getOktaClientFromMetadata(m), d.Get("user_type").(string))
if err != nil {
Expand Down
17 changes: 16 additions & 1 deletion okta/resource_okta_user_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,25 @@ func resourceUserSchema() *schema.Resource {
return []*schema.ResourceData{d}, nil
},
},
Schema: userSchemaSchema,
Schema: buildBaseUserSchema(userSchemaSchema),
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceUserSchemaResourceV0().CoreConfigSchema().ImpliedType(),
Upgrade: func(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
rawState["user_type"] = "default"
return rawState, nil
},
Version: 0,
},
},
}
}

func resourceUserSchemaResourceV0() *schema.Resource {
return &schema.Resource{Schema: buildSchema(userBaseSchemaSchema, userSchemaSchema)}
}

func resourceUserSchemaCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
schemaUrl, err := getUserTypeSchemaUrl(ctx, getOktaClientFromMetadata(m), d.Get("user_type").(string))
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions okta/resource_okta_user_type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,27 @@ import (
"context"
"errors"
"fmt"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func sweepUserTypes(client *testClient) error {
userTypeList, _, _ := client.oktaClient.UserType.ListUserTypes(context.Background())
var errorList []error
for _, ut := range userTypeList {
if strings.HasPrefix(ut.Name, testResourcePrefix) {
if _, err := client.oktaClient.UserType.DeleteUserType(context.Background(), ut.Id); err != nil {
errorList = append(errorList, err)
}
}
}
return condenseError(errorList)
}

func TestAccOktaUserType_crud(t *testing.T) {
ri := acctest.RandInt()
resourceName := fmt.Sprintf("%s.test", userType)
Expand Down
59 changes: 10 additions & 49 deletions okta/user_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,6 @@ import (

var (
userSchemaSchema = map[string]*schema.Schema{
"index": {
Type: schema.TypeString,
Required: true,
Description: "Subschema unique string identifier",
ForceNew: true,
},
"title": {
Type: schema.TypeString,
Required: true,
Description: "Subschema title (display name)",
},
"type": {
Type: schema.TypeString,
Required: true,
ValidateDiagFunc: stringInSlice([]string{"string", "boolean", "number", "integer", "array", "object"}),
Description: "Subschema type: string, boolean, number, integer, array, or object",
ForceNew: true,
},
"array_type": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -64,11 +46,6 @@ var (
Optional: true,
Description: "Custom Subschema description",
},
"required": {
Type: schema.TypeBool,
Optional: true,
Description: "Whether the subschema is required",
},
"min_length": {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -116,20 +93,6 @@ var (
},
},
},
"permissions": {
Type: schema.TypeString,
Optional: true,
ValidateDiagFunc: stringInSlice([]string{"HIDE", "READ_ONLY", "READ_WRITE"}),
Description: "SubSchema permissions: HIDE, READ_ONLY, or READ_WRITE.",
Default: "READ_ONLY",
},
"master": {
Type: schema.TypeString,
Optional: true,
// Accepting an empty value to allow for zero value (when provisioning is off)
ValidateDiagFunc: stringInSlice([]string{"PROFILE_MASTER", "OKTA", ""}),
Description: "SubSchema profile manager, if not set it will inherit its setting.",
},
"external_name": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -149,12 +112,6 @@ var (
ValidateDiagFunc: stringInSlice([]string{"UNIQUE_VALIDATED", "NOT_UNIQUE"}),
ConflictsWith: []string{"one_of", "enum", "array_type"},
},
"user_type": {
Type: schema.TypeString,
Optional: true,
Description: "Custom subschema user type",
Default: "default",
},
}

userBaseSchemaSchema = map[string]*schema.Schema{
Expand Down Expand Up @@ -195,21 +152,25 @@ var (
Optional: true,
Description: "Whether the subschema is required",
},
}

userTypeSchema = map[string]*schema.Schema{
"user_type": {
Type: schema.TypeString,
Optional: true,
Description: "Custom subschema user type",
Default: "default",
Type: schema.TypeString,
Optional: true,
Description: "Custom subschema user type",
Default: "default",
ValidateDiagFunc: stringAtLeast(7),
},
}
)

func buildBaseUserSchema(target map[string]*schema.Schema) map[string]*schema.Schema {
return buildSchema(userBaseSchemaSchema, target)
return buildSchema(userBaseSchemaSchema, userTypeSchema, target)
}

func buildCustomUserSchema(target map[string]*schema.Schema) map[string]*schema.Schema {
return buildSchema(userSchemaSchema, target)
return buildSchema(userSchemaSchema, userBaseSchemaSchema, userTypeSchema, target)
}

func syncUserSchema(d *schema.ResourceData, subschema *sdk.UserSubSchema) error {
Expand Down
15 changes: 14 additions & 1 deletion okta/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,20 @@ func stringLenBetween(min, max int) schema.SchemaValidateDiagFunc {
return diag.Errorf("expected type of %s to be string", k)
}
if len(v) < min || len(v) > max {
return diag.Errorf("expected length of %s to be in the range (%d - %d), got %s", k, min, max, v)
return diag.Errorf("expected length of %s to be in the range (%d - %d), got %d", k, min, max, len(v))
}
return nil
}
}

func stringAtLeast(min int) schema.SchemaValidateDiagFunc {
return func(i interface{}, k cty.Path) diag.Diagnostics {
v, ok := i.(string)
if !ok {
return diag.Errorf("expected type of %s to be string", k)
}
if len(strings.TrimSpace(v)) < min {
return diag.Errorf("expected minimum length of %s to be %d, got %d", k, min, len(v))
}
return nil
}
Expand Down

0 comments on commit f1f1cb7

Please sign in to comment.