Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(organization_user): replaced client-v2 with avngen #1932

Merged
merged 1 commit into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
Loading