Skip to content

Commit

Permalink
refactor(organization_user): replaced client-v2 with avngen (#1932)
Browse files Browse the repository at this point in the history
  • Loading branch information
vmyroslav authored Dec 10, 2024
1 parent aae82a4 commit 821e0e4
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 103 deletions.
79 changes: 37 additions & 42 deletions internal/sdkprovider/service/organization/organization_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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,
},
Expand All @@ -92,87 +93,81 @@ 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
}
}
}

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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ package organization

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/aiven/go-client-codegen/handler/organizationuser"
"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"
"github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig"
)

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{
Expand Down Expand Up @@ -45,55 +47,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: %w", organizationID, err)
}

var found int

var user aiven.OrganizationMemberInfo
for _, u := range rm.Users {
if userEmail != "" && u.UserInfo.UserEmail == userEmail {
user = u
found++
}

if userID != "" && u.UserID == userID {
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 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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -29,22 +30,25 @@ 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"),
),
},
},
})
}

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,
Expand All @@ -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"),
),
},
},
Expand Down
34 changes: 18 additions & 16 deletions internal/sdkprovider/service/organization/organization_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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" {
Expand All @@ -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)
}
Expand Down

0 comments on commit 821e0e4

Please sign in to comment.