diff --git a/internal/sdkprovider/service/project/project_user.go b/internal/sdkprovider/service/project/project_user.go index 46e5e1a1d..9e5eb8e1d 100644 --- a/internal/sdkprovider/service/project/project_user.go +++ b/internal/sdkprovider/service/project/project_user.go @@ -5,9 +5,9 @@ import ( "errors" "strings" - "github.com/aiven/aiven-go-client/v2" + avngen "github.com/aiven/go-client-codegen" "github.com/aiven/go-client-codegen/handler/account" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/aiven/go-client-codegen/handler/project" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/aiven/terraform-provider-aiven/internal/common" @@ -44,10 +44,10 @@ func ResourceProjectUser() *schema.Resource { [migrate existing aiven_project_user resources](https://registry.terraform.io/providers/aiven/aiven/latest/docs/guides/update-deprecated-resources) to the new resource. `, - CreateContext: resourceProjectUserCreate, - ReadContext: resourceProjectUserRead, - UpdateContext: resourceProjectUserUpdate, - DeleteContext: resourceProjectUserDelete, + CreateContext: common.WithGenClient(resourceProjectUserCreate), + ReadContext: common.WithGenClient(resourceProjectUserRead), + UpdateContext: common.WithGenClient(resourceProjectUserUpdate), + DeleteContext: common.WithGenClient(resourceProjectUserDelete), Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, @@ -58,139 +58,160 @@ to the new resource. } } -// isProjectUserAlreadyInvited return true if user already been invited to the project -func isProjectUserAlreadyInvited(err error) bool { - var e aiven.Error - if errors.As(err, &e) { - if strings.Contains(e.Message, "already been invited to this project") && e.Status == 409 { - return true - } - } - return false -} - -func resourceProjectUserCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*aiven.Client) - projectName := d.Get("project").(string) - email := d.Get("email").(string) - err := client.ProjectUsers.Invite( - ctx, - projectName, - aiven.CreateProjectInvitationRequest{ - UserEmail: email, - MemberType: d.Get("member_type").(string), - }, +func resourceProjectUserCreate(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { + var ( + projectName = d.Get("project").(string) + email = d.Get("email").(string) + memberType = d.Get("member_type").(string) ) + + err := client.ProjectInvite(ctx, projectName, &project.ProjectInviteIn{ + MemberType: project.MemberType(memberType), + UserEmail: email, + }) + if err != nil && !isProjectUserAlreadyInvited(err) { - return diag.FromErr(err) + return err } d.SetId(schemautil.BuildResourceID(projectName, email)) - if err := d.Set("accepted", false); err != nil { - return diag.FromErr(err) + + if err = d.Set("accepted", false); err != nil { + return err } - return resourceProjectUserRead(ctx, d, m) + return resourceProjectUserRead(ctx, d, client) } -func resourceProjectUserRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*aiven.Client) - +func resourceProjectUserRead(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { projectName, email, err := schemautil.SplitResourceID2(d.Id()) if err != nil { - return diag.FromErr(err) + return err } - user, invitation, err := client.ProjectUsers.Get(ctx, projectName, email) + pul, err := client.ProjectUserList(ctx, projectName) if err != nil { - if aiven.IsNotFound(err) && !d.Get("accepted").(bool) { - return resourceProjectUserCreate(ctx, d, m) - } - return diag.FromErr(schemautil.ResourceReadHandleNotFound(err, d)) + return err } - if err := d.Set("project", projectName); err != nil { - return diag.FromErr(err) - } - if err := d.Set("email", email); err != nil { - return diag.FromErr(err) - } - if user != nil { - if err := d.Set("member_type", user.MemberType); err != nil { - return diag.FromErr(err) - } - if err := d.Set("accepted", true); err != nil { - return diag.FromErr(err) - } - } else { - if err := d.Set("member_type", invitation.MemberType); err != nil { - return diag.FromErr(err) + for _, user := range pul.Users { + if user.UserEmail == email { + if err = d.Set("member_type", string(user.MemberType)); err != nil { + return err + } + + if err = d.Set("accepted", true); err != nil { + return err + } + + return nil } - if err := d.Set("accepted", false); err != nil { - return diag.FromErr(err) + } + + for _, invitation := range pul.Invitations { + if invitation.InvitedUserEmail == email { + if err = d.Set("member_type", string(invitation.MemberType)); err != nil { + return err + } + + if err = d.Set("accepted", false); err != nil { + return err + } + + return nil } } - return nil -} -func resourceProjectUserUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*aiven.Client) + if !d.Get("accepted").(bool) { + return resourceProjectUserCreate(ctx, d, client) + } + + return schemautil.ResourceReadHandleNotFound(errors.New("project user not found"), d) +} +func resourceProjectUserUpdate(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { projectName, email, err := schemautil.SplitResourceID2(d.Id()) if err != nil { - return diag.FromErr(err) + return err } memberType := d.Get("member_type").(string) - err = client.ProjectUsers.UpdateUserOrInvitation( + err = client.ProjectUserUpdate( ctx, projectName, email, - aiven.UpdateProjectUserOrInvitationRequest{ - MemberType: memberType, - }, + &project.ProjectUserUpdateIn{MemberType: project.MemberType(memberType)}, ) - if err != nil { - return diag.FromErr(err) + + if err == nil { + return resourceProjectUserRead(ctx, d, client) } - return resourceProjectUserRead(ctx, d, m) -} + if common.IsCritical(err) { + return err + } -func resourceProjectUserDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*aiven.Client) + // if user not found, delete the user invite and re-invite + if err = client.ProjectInviteDelete(ctx, projectName, email); err != nil { + return err + } + + if err = client.ProjectInvite(ctx, projectName, &project.ProjectInviteIn{ + MemberType: project.MemberType(memberType), + UserEmail: email, + }); err != nil { + return err + } + return resourceProjectUserRead(ctx, d, client) +} + +func resourceProjectUserDelete(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { projectName, email, err := schemautil.SplitResourceID2(d.Id()) if err != nil { - return diag.FromErr(err) + return err } - user, invitation, err := client.ProjectUsers.Get(ctx, projectName, email) + pul, err := client.ProjectUserList(ctx, projectName) if err != nil { - return diag.FromErr(err) + return err } // delete user if exists - if user != nil { - err := client.ProjectUsers.DeleteUser(ctx, projectName, email) - if err != nil { - var e aiven.Error - if errors.As(err, &e) && e.Status != 404 || - !strings.Contains(e.Message, "User does not exist") || - !strings.Contains(e.Message, "User not found") { - - return diag.FromErr(err) + for _, user := range pul.Users { + if user.UserEmail == email { + if err = client.ProjectUserRemove(ctx, projectName, email); err != nil { + var e avngen.Error + if errors.As(err, &e) && e.Status != 404 || + !strings.Contains(e.Message, "User does not exist") || + !strings.Contains(e.Message, "User not found") { + + return err + } } } } // delete invitation if exists - if invitation != nil { - err := client.ProjectUsers.DeleteInvitation(ctx, projectName, email) - if common.IsCritical(err) { - return diag.FromErr(err) + for _, invitation := range pul.Invitations { + if invitation.InvitedUserEmail == email { + if err = client.ProjectInviteDelete(ctx, projectName, email); common.IsCritical(err) { + return err + } } } return nil } + +// isProjectUserAlreadyInvited return true if user already been invited to the project +func isProjectUserAlreadyInvited(err error) bool { + var e avngen.Error + if errors.As(err, &e) { + if strings.Contains(e.Message, "already been invited to this project") && e.Status == 409 { + return true + } + } + + return false +} diff --git a/internal/sdkprovider/service/project/project_user_data_source.go b/internal/sdkprovider/service/project/project_user_data_source.go index 3e2228dbe..2458c2a79 100644 --- a/internal/sdkprovider/service/project/project_user_data_source.go +++ b/internal/sdkprovider/service/project/project_user_data_source.go @@ -2,46 +2,50 @@ package project import ( "context" + "fmt" - "github.com/aiven/aiven-go-client/v2" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + avngen "github.com/aiven/go-client-codegen" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/aiven/terraform-provider-aiven/internal/common" "github.com/aiven/terraform-provider-aiven/internal/schemautil" ) func DatasourceProjectUser() *schema.Resource { return &schema.Resource{ - ReadContext: datasourceProjectUserRead, + ReadContext: common.WithGenClient(datasourceProjectUserRead), Description: "The Project User data source provides information about the existing Aiven Project User.", Schema: schemautil.ResourceSchemaAsDatasourceSchema(aivenProjectUserSchema, "project", "email"), } } -func datasourceProjectUserRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*aiven.Client) +func datasourceProjectUserRead(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { + var ( + projectName = d.Get("project").(string) + email = d.Get("email").(string) + ) - projectName := d.Get("project").(string) - email := d.Get("email").(string) - - users, invitations, err := client.ProjectUsers.List(ctx, projectName) + pul, err := client.ProjectUserList(ctx, projectName) if err != nil { - return diag.FromErr(err) + return err } - for _, user := range users { - if user.Email == email { + + for _, user := range pul.Users { + if user.UserEmail == email { d.SetId(schemautil.BuildResourceID(projectName, email)) - return resourceProjectUserRead(ctx, d, m) + + return resourceProjectUserRead(ctx, d, client) } } - for _, invitation := range invitations { - if invitation.UserEmail == email { + for _, invitation := range pul.Invitations { + if invitation.InvitedUserEmail == email { d.SetId(schemautil.BuildResourceID(projectName, email)) - return resourceProjectUserRead(ctx, d, m) + + return resourceProjectUserRead(ctx, d, client) } } - return diag.Errorf("project user %s/%s not found", projectName, email) + return fmt.Errorf("project user %s/%s not found", projectName, email) } diff --git a/internal/sdkprovider/service/project/project_user_test.go b/internal/sdkprovider/service/project/project_user_test.go index 06f61100b..d8f52d7e7 100644 --- a/internal/sdkprovider/service/project/project_user_test.go +++ b/internal/sdkprovider/service/project/project_user_test.go @@ -6,7 +6,7 @@ import ( "fmt" "testing" - "github.com/aiven/aiven-go-client/v2" + avngen "github.com/aiven/go-client-codegen" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -48,7 +48,10 @@ func TestAccAivenProjectUser_basic(t *testing.T) { } func testAccCheckAivenProjectUserResourceDestroy(s *terraform.State) error { - c := acc.GetTestAivenClient() + c, err := acc.GetTestGenAivenClient() + if err != nil { + return fmt.Errorf("error instantiating client: %w", err) + } ctx := context.Background() @@ -63,20 +66,24 @@ func testAccCheckAivenProjectUserResourceDestroy(s *terraform.State) error { return err } - p, i, err := c.ProjectUsers.Get(ctx, projectName, email) + pul, err := c.ProjectUserList(ctx, projectName) if err != nil { - var e aiven.Error + var e avngen.Error if errors.As(err, &e) && e.Status != 404 && e.Status != 403 { return err } } - if p != nil { - return fmt.Errorf("porject user (%s) still exists", rs.Primary.ID) + for _, user := range pul.Users { + if user.UserEmail == email { + return fmt.Errorf("porject user (%s) still exists", rs.Primary.ID) + } } - if i != nil { - return fmt.Errorf("porject user invitation (%s) still exists", rs.Primary.ID) + for _, invitation := range pul.Invitations { + if invitation.InvitedUserEmail == email { + return fmt.Errorf("porject user invitation (%s) still exists", rs.Primary.ID) + } } }