From c48c864277eb35526fbd616a6f6faeede5834fc4 Mon Sep 17 00:00:00 2001 From: michiel de wilde Date: Fri, 5 Apr 2024 13:27:38 +0200 Subject: [PATCH] Handle import for users with no invitation email (#534) --- docs/resources/user.md | 5 ++++- spacelift/internal/structs/user_input.go | 2 +- spacelift/resource_user.go | 25 +++++++++++++++++------- spacelift/resource_user_test.go | 18 +++++++++++++++++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/docs/resources/user.md b/docs/resources/user.md index 0db7c8bb..e08aa9db 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -17,10 +17,13 @@ description: |- ### Required -- `invitation_email` (String) Email of the user. Used for sending an invitation. - `policy` (Block List, Min: 1) (see [below for nested schema](#nestedblock--policy)) - `username` (String) Username of the user +### Optional + +- `invitation_email` (String) `invitation_email` will be used to send an invitation to the specified email address. This property is required when creating a new user. This property is optional when importing an existing user. + ### Read-Only - `id` (String) The ID of this resource. diff --git a/spacelift/internal/structs/user_input.go b/spacelift/internal/structs/user_input.go index 2edfceed..0417b835 100644 --- a/spacelift/internal/structs/user_input.go +++ b/spacelift/internal/structs/user_input.go @@ -3,7 +3,7 @@ package structs import "github.com/shurcooL/graphql" type ManagedUserInviteInput struct { - InvitationEmail graphql.String `json:"invitationEmail"` + InvitationEmail *graphql.String `json:"invitationEmail"` Username graphql.String `json:"username"` AccessRules []SpaceAccessRuleInput `json:"accessRules"` } diff --git a/spacelift/resource_user.go b/spacelift/resource_user.go index b0afaab9..b83d1004 100644 --- a/spacelift/resource_user.go +++ b/spacelift/resource_user.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/shurcooL/graphql" "github.com/spacelift-io/terraform-provider-spacelift/spacelift/internal" "github.com/spacelift-io/terraform-provider-spacelift/spacelift/internal/structs" @@ -28,15 +29,10 @@ func resourceUser() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "invitation_email": { - Type: schema.TypeString, - Description: "Email of the user. Used for sending an invitation.", - Required: true, - }, "username": { Type: schema.TypeString, - Description: "Username of the user", Required: true, + Description: "Username of the user", }, "policy": { Type: schema.TypeList, @@ -60,6 +56,11 @@ func resourceUser() *schema.Resource { }, }, }, + "invitation_email": { + Type: schema.TypeString, + Optional: true, + Description: "`invitation_email` will be used to send an invitation to the specified email address. This property is required when creating a new user. This property is optional when importing an existing user.", + }, }, } } @@ -69,9 +70,19 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, i interface var mutation struct { User *structs.User `graphql:"managedUserInvite(input: $input)"` } + + var email *graphql.String + if d.Get("invitation_email") != "" { + email = toOptionalString(d.Get("invitation_email")) + } + + if email == nil || *email == "" { + return diag.Errorf("invitation_email is required for new users") + } + variables := map[string]interface{}{ "input": structs.ManagedUserInviteInput{ - InvitationEmail: toString(d.Get("invitation_email")), + InvitationEmail: email, Username: toString(d.Get("username")), AccessRules: getAccessRules(d), }, diff --git a/spacelift/resource_user_test.go b/spacelift/resource_user_test.go index fcac520e..020d91b6 100644 --- a/spacelift/resource_user_test.go +++ b/spacelift/resource_user_test.go @@ -63,6 +63,24 @@ func TestUserResource(t *testing.T) { }) }) + t.Run("creates a user without invitation email returns an error", func(t *testing.T) { + randomUsername := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + testSteps(t, []resource.TestStep{ + { + Config: fmt.Sprintf(` + resource "spacelift_user" "test" { + username = "%s" + policy { + space_id = "root" + role = "ADMIN" + } + }`, randomUsername), + ExpectError: regexp.MustCompile(`invitation_email is required for new users`), + }, + }) + }) + t.Run("can edit access list", func(t *testing.T) { randomUsername := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) exampleEmail := fmt.Sprintf("%s@example.com", randomUsername)