From 64d0f8259407e557da635a61359d0b429ad1158f Mon Sep 17 00:00:00 2001 From: Myroslav Vivcharyk Date: Mon, 9 Dec 2024 17:49:38 +0100 Subject: [PATCH] refactor(organization_user): replaced client-v2 with avngen --- .../service/organization/organization_user.go | 79 +++++++++---------- .../organization_user_data_source.go | 79 ++++++++++--------- .../organization_user_data_source_test.go | 22 ++++-- .../organization/organization_user_test.go | 34 ++++---- 4 files changed, 111 insertions(+), 103 deletions(-) diff --git a/internal/sdkprovider/service/organization/organization_user.go b/internal/sdkprovider/service/organization/organization_user.go index 5bbfddbcc..ad3cb6af3 100644 --- a/internal/sdkprovider/service/organization/organization_user.go +++ b/internal/sdkprovider/service/organization/organization_user.go @@ -2,8 +2,9 @@ package organization import ( "context" + "fmt" - "github.com/aiven/aiven-go-client/v2" + avngen "github.com/aiven/go-client-codegen" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -66,8 +67,8 @@ data source. You can manage user access to projects with the ` + "`aiven_organiz ` + "`aiven_organization_user_group_member`" + `, and ` + "`aiven_organization_permission`" + ` resources. `, CreateContext: resourceOrganizationUserCreate, - ReadContext: resourceOrganizationUserRead, - DeleteContext: resourceOrganizationUserDelete, + ReadContext: common.WithGenClient(resourceOrganizationUserRead), + DeleteContext: common.WithGenClient(resourceOrganizationUserDelete), Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, @@ -92,34 +93,30 @@ func resourceOrganizationUserCreate(_ context.Context, _ *schema.ResourceData, _ } // resourceOrganizationUserRead reads the properties of an Aiven Organization User and provides them to Terraform -func resourceOrganizationUserRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*aiven.Client) - +func resourceOrganizationUserRead(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { organizationID, userEmail, err := schemautil.SplitResourceID2(d.Id()) if err != nil { - return diag.FromErr(err) + return err } - rm, err := client.OrganizationUser.List(ctx, organizationID) + resp, err := client.OrganizationUserList(ctx, organizationID) if err != nil { - return diag.FromErr(err) + return err } - for _, user := range rm.Users { - userInfo := user.UserInfo - - if userInfo.UserEmail == userEmail { - if err := d.Set("organization_id", organizationID); err != nil { - return diag.FromErr(err) + for _, user := range resp { + if user.UserInfo.UserEmail == userEmail { + if err = d.Set("organization_id", organizationID); err != nil { + return err } - if err := d.Set("user_email", userInfo.UserEmail); err != nil { - return diag.FromErr(err) + if err = d.Set("user_email", userEmail); err != nil { + return err } - if err := d.Set("create_time", user.JoinTime.String()); err != nil { - return diag.FromErr(err) + if err = d.Set("create_time", user.JoinTime.String()); err != nil { + return err } - if err := d.Set("user_id", user.UserID); err != nil { - return diag.FromErr(err) + if err = d.Set("user_id", user.UserId); err != nil { + return err } } } @@ -127,52 +124,50 @@ func resourceOrganizationUserRead(ctx context.Context, d *schema.ResourceData, m return nil } -func resourceOrganizationUserDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*aiven.Client) +func resourceOrganizationUserDelete(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { + var invitationFound = true organizationID, userEmail, err := schemautil.SplitResourceID2(d.Id()) if err != nil { - return diag.FromErr(err) + return err } - found := true - // delete organization user invitation - err = client.OrganizationUserInvitations.Delete(ctx, organizationID, userEmail) + err = client.OrganizationUserInvitationDelete(ctx, organizationID, userEmail) if err != nil { - if !aiven.IsNotFound(err) { - return diag.FromErr(err) + if !avngen.IsNotFound(err) { + return err } - found = false + invitationFound = false } - r, err := client.OrganizationUser.List(ctx, organizationID) + resp, err := client.OrganizationUserList(ctx, organizationID) if err != nil { - return diag.FromErr(err) + return err } - if len(r.Users) == 0 { + if len(resp) == 0 { return nil } // delete organization user - for _, u := range r.Users { + for _, u := range resp { userInfo := u.UserInfo if userInfo.UserEmail == userEmail { - err = client.OrganizationUser.Delete(ctx, organizationID, u.UserID) - if common.IsCritical(err) { - return diag.FromErr(err) + err = client.OrganizationUserDelete(ctx, organizationID, u.UserId) + if err != nil && !avngen.IsNotFound(err) { + return err } - found = true - break + + return nil } } - if !found { - return diag.Errorf("user with email %q is not a part of the organization %q", userEmail, organizationID) + if invitationFound { + return nil } - return nil + return fmt.Errorf("user with email %q is not a part of the organization %q", userEmail, organizationID) } diff --git a/internal/sdkprovider/service/organization/organization_user_data_source.go b/internal/sdkprovider/service/organization/organization_user_data_source.go index dbd1eea0f..fc1525306 100644 --- a/internal/sdkprovider/service/organization/organization_user_data_source.go +++ b/internal/sdkprovider/service/organization/organization_user_data_source.go @@ -2,9 +2,13 @@ package organization import ( "context" + "fmt" - "github.com/aiven/aiven-go-client/v2" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/aiven/go-client-codegen/handler/organizationuser" + + "github.com/aiven/terraform-provider-aiven/internal/common" + + avngen "github.com/aiven/go-client-codegen" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/aiven/terraform-provider-aiven/internal/schemautil" @@ -13,7 +17,7 @@ import ( func DatasourceOrganizationUser() *schema.Resource { return &schema.Resource{ - ReadContext: datasourceOrganizationUserRead, + ReadContext: common.WithGenClient(datasourceOrganizationUserRead), Description: "The Organization User data source provides information about the existing Aiven" + " Organization User.", Schema: map[string]*schema.Schema{ @@ -45,55 +49,56 @@ func DatasourceOrganizationUser() *schema.Resource { } // datasourceOrganizationUserRead reads the specified Organization User data source. -func datasourceOrganizationUserRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - organizationID := d.Get("organization_id").(string) - userEmail := d.Get("user_email").(string) - userID := d.Get("user_id").(string) +func datasourceOrganizationUserRead(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { + var ( + organizationID = d.Get("organization_id").(string) + userEmail = d.Get("user_email").(string) + userID = d.Get("user_id").(string) + + orgUser organizationuser.UserOut + ) if userEmail == "" && userID == "" { - return diag.Errorf("either user_email or user_id must be specified") + return fmt.Errorf("either user_email or user_id must be specified") } - client := m.(*aiven.Client) - rm, err := client.OrganizationUser.List(ctx, organizationID) + rm, err := client.OrganizationUserList(ctx, organizationID) if err != nil { - return diag.Errorf("cannot get organization [%s] user list: %s", organizationID, err) + return fmt.Errorf("cannot get organization [%s] user list: %s", organizationID, err) } - var found int - - var user aiven.OrganizationMemberInfo - for _, u := range rm.Users { - if userEmail != "" && u.UserInfo.UserEmail == userEmail { - user = u - found++ + // Find the organization user by email or ID + var matchedUsers []organizationuser.UserOut + for _, u := range rm { + if (userEmail != "" && u.UserInfo.UserEmail == userEmail) || + (userID != "" && u.UserId == userID) { + matchedUsers = append(matchedUsers, u) } - - if userID != "" && u.UserID == userID { - user = u - found++ - } - } - - if found == 0 { - return diag.Errorf("organization user %s not found in organization %s", userEmail, organizationID) } - if found > 1 { - return diag.Errorf("multiple organization users %s found in organization %s", userEmail, organizationID) + // Check if the only one user was found + switch len(matchedUsers) { + case 0: + return fmt.Errorf("organization user %s not found in organization %s", + userEmail, organizationID) + case 1: + orgUser = matchedUsers[0] + default: + return fmt.Errorf("multiple organization users %s found in organization %s", + userEmail, organizationID) } - if err := d.Set("organization_id", organizationID); err != nil { - return diag.FromErr(err) + if err = d.Set("organization_id", organizationID); err != nil { + return err } - if err := d.Set("user_email", user.UserInfo.UserEmail); err != nil { - return diag.FromErr(err) + if err = d.Set("user_email", orgUser.UserInfo.UserEmail); err != nil { + return err } - if err := d.Set("create_time", user.JoinTime.String()); err != nil { - return diag.FromErr(err) + if err = d.Set("create_time", orgUser.JoinTime.String()); err != nil { + return err } - if err := d.Set("user_id", user.UserID); err != nil { - return diag.FromErr(err) + if err = d.Set("user_id", orgUser.UserId); err != nil { + return err } d.SetId(schemautil.BuildResourceID(organizationID, userEmail)) diff --git a/internal/sdkprovider/service/organization/organization_user_data_source_test.go b/internal/sdkprovider/service/organization/organization_user_data_source_test.go index b60e57251..54c9001a5 100644 --- a/internal/sdkprovider/service/organization/organization_user_data_source_test.go +++ b/internal/sdkprovider/service/organization/organization_user_data_source_test.go @@ -11,15 +11,16 @@ import ( ) func TestAccAivenOrganizationUserDataSource_using_email(t *testing.T) { - orgID := os.Getenv("AIVEN_ORG_ID") - email := os.Getenv("AIVEN_ORG_USER_EMAIL") + var ( + orgID = os.Getenv("AIVEN_ORG_ID") + email = os.Getenv("AIVEN_ORG_USER_EMAIL") + datasourceName = "data.aiven_organization_user.member" + ) if orgID == "" || email == "" { t.Skip("Skipping test due to missing AIVEN_ORG_ID or AIVEN_ORG_USER_EMAIL environment variable") } - datasourceName := "data.aiven_organization_user.member" - resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acc.TestAccPreCheck(t) }, ProtoV6ProviderFactories: acc.TestProtoV6ProviderFactories, @@ -29,6 +30,8 @@ func TestAccAivenOrganizationUserDataSource_using_email(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet(datasourceName, "user_email"), resource.TestCheckResourceAttrSet(datasourceName, "create_time"), + resource.TestCheckResourceAttrSet(datasourceName, "user_id"), + resource.TestCheckResourceAttrSet(datasourceName, "organization_id"), ), }, }, @@ -36,15 +39,16 @@ func TestAccAivenOrganizationUserDataSource_using_email(t *testing.T) { } func TestAccAivenOrganizationUserDataSource_using_userid(t *testing.T) { - orgID := os.Getenv("AIVEN_ORG_ID") - userID := os.Getenv("AIVEN_ORG_USER_ID") + var ( + orgID = os.Getenv("AIVEN_ORG_ID") + userID = os.Getenv("AIVEN_ORG_USER_ID") + datasourceName = "data.aiven_organization_user.member" + ) if orgID == "" || userID == "" { t.Skip("Skipping test due to missing AIVEN_ORG_ID or AIVEN_ORG_USER_ID environment variable") } - datasourceName := "data.aiven_organization_user.member" - resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acc.TestAccPreCheck(t) }, ProtoV6ProviderFactories: acc.TestProtoV6ProviderFactories, @@ -54,6 +58,8 @@ func TestAccAivenOrganizationUserDataSource_using_userid(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet(datasourceName, "user_id"), resource.TestCheckResourceAttrSet(datasourceName, "create_time"), + resource.TestCheckResourceAttrSet(datasourceName, "user_id"), + resource.TestCheckResourceAttrSet(datasourceName, "organization_id"), ), }, }, diff --git a/internal/sdkprovider/service/organization/organization_user_test.go b/internal/sdkprovider/service/organization/organization_user_test.go index 3637aa1d9..b983255e2 100644 --- a/internal/sdkprovider/service/organization/organization_user_test.go +++ b/internal/sdkprovider/service/organization/organization_user_test.go @@ -2,12 +2,11 @@ package organization_test import ( "context" - "errors" "fmt" "regexp" "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" @@ -54,9 +53,14 @@ data "aiven_organization_user" "member" { } func testAccCheckAivenOrganizationUserResourceDestroy(s *terraform.State) error { - c := acc.GetTestAivenClient() + var ( + c, err = acc.GetTestGenAivenClient() + ctx = context.Background() + ) - ctx := context.Background() + if err != nil { + return fmt.Errorf("error getting generated Aiven client: %w", err) + } for _, rs := range s.RootModule().Resources { if rs.Type != "aiven_organization_user" { @@ -68,28 +72,26 @@ func testAccCheckAivenOrganizationUserResourceDestroy(s *terraform.State) error return err } - r, err := c.Organization.Get(ctx, organizationID) + resp, err := c.OrganizationGet(ctx, organizationID) if err != nil { - var e aiven.Error - if errors.As(err, &e) && e.Status != 404 { - return err + if avngen.IsNotFound(err) { + return nil } - return nil + return err } - if r.ID == organizationID { - ri, err := c.OrganizationUserInvitations.List(ctx, organizationID) + if resp.OrganizationId == organizationID { + respI, err := c.OrganizationUserInvitationsList(ctx, organizationID) if err != nil { - var e aiven.Error - if errors.As(err, &e) && e.Status != 404 { - return err + if avngen.IsNotFound(err) { + return nil } - return nil + return err } - for _, i := range ri.Invitations { + for _, i := range respI { if i.UserEmail == userEmail { return fmt.Errorf("organization user (%s) still exists", rs.Primary.ID) }