From ae65f1baf530b10a3f027a39c3c9d638615592f2 Mon Sep 17 00:00:00 2001 From: Dzmitry Kishylau Date: Mon, 9 Sep 2024 13:29:33 -0700 Subject: [PATCH] [fix] Set default creation options when importing retool_space resource --- internal/provider/space/resource.go | 54 +++++++++++++++++------- internal/provider/space/resource_test.go | 26 ++++++++++++ 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/internal/provider/space/resource.go b/internal/provider/space/resource.go index f538f6e..4969afc 100644 --- a/internal/provider/space/resource.go +++ b/internal/provider/space/resource.go @@ -8,6 +8,7 @@ import ( "github.com/tryretool/terraform-provider-retool/internal/sdk/api" "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" @@ -49,20 +50,11 @@ type spaceCreateOptionsModel struct { CreateAdminUser types.Bool `tfsdk:"create_admin_user"` } -// Create new Space resource. -func NewResource() resource.Resource { - return &spaceResource{} -} - -func (r *spaceResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_space" -} - -func (r *spaceResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { - emptyList, diags := types.ListValue(types.StringType, []attr.Value{}) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return +func getDefaultCreateOptions(diags *diag.Diagnostics) *basetypes.ObjectValue { + emptyList, localDiags := types.ListValue(types.StringType, []attr.Value{}) + diags.Append(localDiags...) + if diags.HasError() { + return nil } defaultCreateOptionsTypes := map[string]attr.Type{ @@ -77,12 +69,35 @@ func (r *spaceResource) Schema(_ context.Context, _ resource.SchemaRequest, resp "users_to_copy_as_admins": emptyList, "create_admin_user": types.BoolValue(true), } - defaultCreateOptions, diags := types.ObjectValue(defaultCreateOptionsTypes, defaultCreateOptionsValues) + defaultCreateOptions, localDiags := types.ObjectValue(defaultCreateOptionsTypes, defaultCreateOptionsValues) + diags.Append(localDiags...) + if diags.HasError() { + return nil + } + return &defaultCreateOptions +} + +// Create new Space resource. +func NewResource() resource.Resource { + return &spaceResource{} +} + +func (r *spaceResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_space" +} + +func (r *spaceResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + emptyList, diags := types.ListValue(types.StringType, []attr.Value{}) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } + defaultCreateOptions := getDefaultCreateOptions(&resp.Diagnostics) + if resp.Diagnostics.HasError() || defaultCreateOptions == nil { + return + } + resp.Schema = schema.Schema{ Description: "Space resource allows you to create and manage Spaces in Retool. The provider must be configured using the hostname of the admin Space.", Attributes: map[string]schema.Attribute{ @@ -144,7 +159,7 @@ func (r *spaceResource) Schema(_ context.Context, _ resource.SchemaRequest, resp }, }, }, - Default: objectdefault.StaticValue(defaultCreateOptions), + Default: objectdefault.StaticValue(*defaultCreateOptions), PlanModifiers: []planmodifier.Object{ objectplanmodifier.UseStateForUnknown(), objectplanmodifier.RequiresReplace(), @@ -318,4 +333,11 @@ func (r *spaceResource) Delete(ctx context.Context, req resource.DeleteRequest, func (r *spaceResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { // Retrieve import ID and save to id attribute. resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) + + // Need to set default create options so that TF doesn't attempt to re-create the space. + defaultCreateOptions := getDefaultCreateOptions(&resp.Diagnostics) + if resp.Diagnostics.HasError() || defaultCreateOptions == nil { + return + } + resp.State.SetAttribute(ctx, path.Root("create_options"), *defaultCreateOptions) } diff --git a/internal/provider/space/resource_test.go b/internal/provider/space/resource_test.go index 1aabbc5..582c88b 100644 --- a/internal/provider/space/resource_test.go +++ b/internal/provider/space/resource_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/tryretool/terraform-provider-retool/internal/acctest" ) @@ -69,6 +70,31 @@ func TestAccSpace(t *testing.T) { { ResourceName: "retool_space.test_space", ImportState: true, + ImportStateCheck: func(state []*terraform.InstanceState) error { + if len(state) != 1 { + return fmt.Errorf("Unexpected number of objects in state %d", len(state)) + } + stateObj := state[0] + if stateObj.Attributes["name"] != "tf-acc-test-space" { + return fmt.Errorf("Unexpected name %s", stateObj.Attributes["name"]) + } + if stateObj.Attributes["domain"] != "tfspace.localhost" { + return fmt.Errorf("Unexpected domain %s", stateObj.Attributes["domain"]) + } + if stateObj.Attributes["create_options.copy_sso_settings"] != "false" { + return fmt.Errorf("Unexpected copy_sso_settings %s", stateObj.Attributes["create_options.copy_sso_settings"]) + } + if stateObj.Attributes["create_options.copy_branding_and_themes_settings"] != "false" { + return fmt.Errorf("Unexpected copy_branding_and_themes_settings %s", stateObj.Attributes["create_options.copy_branding_and_themes_settings"]) + } + if stateObj.Attributes["create_options.create_admin_user"] != "true" { + return fmt.Errorf("Unexpected create_admin_user %s", stateObj.Attributes["create_options.create_admin_user"]) + } + if stateObj.Attributes["create_options.users_to_copy_as_admins.#"] != "0" { + return fmt.Errorf("Unexpected users_to_copy_as_admins %s", stateObj.Attributes["create_options.users_to_copy_as_admins.#"]) + } + return nil + }, }, // Update and Read. {