-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into iam_federations
Showing
12 changed files
with
809 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
package selectel | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func resourceIAMGroupMembershipV1() *schema.Resource { | ||
return &schema.Resource{ | ||
CreateContext: resourceIAMGroupMembershipV1Create, | ||
ReadContext: resourceIAMGroupMembershipV1Read, | ||
UpdateContext: resourceIAMGroupMembershipV1Update, | ||
DeleteContext: resourceIAMGroupMembershipV1Delete, | ||
Schema: map[string]*schema.Schema{ | ||
"group_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"user_ids": { | ||
Type: schema.TypeList, | ||
Required: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceIAMGroupMembershipV1Create(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
iamClient, diagErr := getIAMClient(meta) | ||
if diagErr != nil { | ||
return diagErr | ||
} | ||
|
||
userIDsInterface := d.Get("user_ids").([]interface{}) | ||
userIDs := make([]string, len(userIDsInterface)) | ||
for i, v := range userIDsInterface { | ||
userIDs[i] = v.(string) | ||
} | ||
log.Print(msgCreate(objectGroupMembership, userIDs)) | ||
|
||
if len(userIDs) == 0 { | ||
createErr := fmt.Errorf("error creating group membership: no user ids specified") | ||
return diag.FromErr(errCreatingObject(objectGroupMembership, createErr)) | ||
} | ||
err := iamClient.Groups.AddUsers(ctx, d.Get("group_id").(string), userIDs) | ||
if err != nil { | ||
return diag.FromErr(errCreatingObject(objectGroupMembership, err)) | ||
} | ||
|
||
d.SetId(d.Get("group_id").(string)) | ||
|
||
return resourceIAMGroupMembershipV1Read(ctx, d, meta) | ||
} | ||
|
||
func resourceIAMGroupMembershipV1Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
iamClient, diagErr := getIAMClient(meta) | ||
if diagErr != nil { | ||
return diagErr | ||
} | ||
|
||
groupID := d.Id() | ||
|
||
userIDsInterface := d.Get("user_ids").([]interface{}) | ||
userIDs := make([]string, len(userIDsInterface)) | ||
for i, v := range userIDsInterface { | ||
userIDs[i] = v.(string) | ||
} | ||
|
||
response, err := iamClient.Groups.Get(ctx, groupID) | ||
if err != nil { | ||
return diag.FromErr(errGettingObject(objectGroupMembership, d.Id(), err)) | ||
} | ||
|
||
responseUserIDs := make([]string, 0) | ||
for _, user := range response.Users { | ||
responseUserIDs = append(responseUserIDs, user.KeystoneID) | ||
} | ||
|
||
responseServiceUserIDs := make([]string, 0) | ||
for _, serviceUser := range response.ServiceUsers { | ||
responseServiceUserIDs = append(responseServiceUserIDs, serviceUser.ID) | ||
} | ||
|
||
d.Set("group_id", groupID) | ||
d.Set("user_ids", append(responseUserIDs, responseServiceUserIDs...)) | ||
|
||
return nil | ||
} | ||
|
||
func resourceIAMGroupMembershipV1Update(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
iamClient, diagErr := getIAMClient(meta) | ||
if diagErr != nil { | ||
return diagErr | ||
} | ||
|
||
groupID := d.Id() | ||
|
||
oldValue, newValue := d.GetChange("user_ids") | ||
|
||
oldUserIDs := make(map[string]struct{}) | ||
for _, v := range oldValue.([]interface{}) { | ||
oldUserIDs[v.(string)] = struct{}{} | ||
} | ||
|
||
newUserIDs := make(map[string]struct{}) | ||
for _, v := range newValue.([]interface{}) { | ||
newUserIDs[v.(string)] = struct{}{} | ||
} | ||
|
||
usersToAdd, usersToRemove := diffUsers(oldUserIDs, newUserIDs) | ||
|
||
if len(usersToAdd) > 0 { | ||
err := iamClient.Groups.AddUsers(ctx, groupID, usersToAdd) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
} | ||
|
||
if len(usersToRemove) > 0 { | ||
err := iamClient.Groups.DeleteUsers(ctx, groupID, usersToRemove) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
} | ||
|
||
d.SetId(groupID) | ||
|
||
return resourceIAMGroupMembershipV1Read(ctx, d, meta) | ||
} | ||
|
||
func resourceIAMGroupMembershipV1Delete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
iamClient, diagErr := getIAMClient(meta) | ||
if diagErr != nil { | ||
return diagErr | ||
} | ||
|
||
groupID := d.Id() | ||
|
||
userIDsInterface := d.Get("user_ids").([]interface{}) | ||
userIDs := make([]string, len(userIDsInterface)) | ||
for i, v := range userIDsInterface { | ||
userIDs[i] = v.(string) | ||
} | ||
|
||
err := iamClient.Groups.DeleteUsers(ctx, groupID, userIDs) | ||
if err != nil { | ||
return diag.FromErr(errDeletingObject(objectGroupMembership, d.Id(), err)) | ||
} | ||
|
||
d.SetId("") | ||
|
||
return nil | ||
} | ||
|
||
func diffUsers(oldUsers, newUsers map[string]struct{}) ([]string, []string) { | ||
usersToAdd := make([]string, 0) | ||
usersToRemove := make([]string, 0) | ||
|
||
for id := range newUsers { | ||
if _, ok := oldUsers[id]; !ok { | ||
usersToAdd = append(usersToAdd, id) | ||
} | ||
} | ||
|
||
for id := range oldUsers { | ||
if _, ok := newUsers[id]; !ok { | ||
usersToRemove = append(usersToRemove, id) | ||
} | ||
} | ||
|
||
return usersToAdd, usersToRemove | ||
} |
136 changes: 136 additions & 0 deletions
136
selectel/resource_selectel_iam_group_membership_v1_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package selectel | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
) | ||
|
||
func TestAccIAMV1GroupMembershipBasic(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccSelectelPreCheck(t) }, | ||
ProviderFactories: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccIAMV1GroupMembershipBasic(), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "id"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "group_id"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "user_ids.0"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccIAMV1GroupUpdate(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccSelectelPreCheck(t) }, | ||
ProviderFactories: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccIAMV1GroupMembershipBasic(), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "id"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "group_id"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "user_ids.0"), | ||
), | ||
}, | ||
{ | ||
Config: testAccIAMV1GroupMembershipUpdate(), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "id"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "group_id"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "user_ids.0"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "user_ids.1"), | ||
), | ||
}, | ||
{ | ||
Config: testAccIAMV1GroupMembershipBasic(), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "id"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "group_id"), | ||
resource.TestCheckResourceAttrSet("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "user_ids.0"), | ||
resource.TestCheckNoResourceAttr("selectel_iam_group_membership_v1.membership_tf_acc_test_1", "user_ids.1"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccIAMV1GroupMembershipBasic() string { | ||
return ` | ||
resource "selectel_iam_serviceuser_v1" "serviceuser_tf_acc_test_1" { | ||
name = "test-service-user-1" | ||
password = "Qazwsxedc123" | ||
role { | ||
role_name = "reader" | ||
scope = "account" | ||
} | ||
} | ||
resource "selectel_iam_serviceuser_v1" "serviceuser_tf_acc_test_2" { | ||
name = "test-service-user-2" | ||
password = "Qazwsxedc123" | ||
role { | ||
role_name = "reader" | ||
scope = "account" | ||
} | ||
} | ||
resource "selectel_iam_group_v1" "group_tf_acc_test_1" { | ||
name = "test-group" | ||
role { | ||
role_name = "reader" | ||
scope = "account" | ||
} | ||
} | ||
resource "selectel_iam_group_membership_v1" "membership_tf_acc_test_1" { | ||
group_id = selectel_iam_group_v1.group_tf_acc_test_1.id | ||
user_ids = [ | ||
selectel_iam_serviceuser_v1.serviceuser_tf_acc_test_1.id | ||
] | ||
} | ||
` | ||
} | ||
|
||
func testAccIAMV1GroupMembershipUpdate() string { | ||
return ` | ||
resource "selectel_iam_serviceuser_v1" "serviceuser_tf_acc_test_1" { | ||
name = "test-service-user-1" | ||
password = "Qazwsxedc123" | ||
role { | ||
role_name = "reader" | ||
scope = "account" | ||
} | ||
} | ||
resource "selectel_iam_serviceuser_v1" "serviceuser_tf_acc_test_2" { | ||
name = "test-service-user-2" | ||
password = "Qazwsxedc123" | ||
role { | ||
role_name = "reader" | ||
scope = "account" | ||
} | ||
} | ||
resource "selectel_iam_group_v1" "group_tf_acc_test_1" { | ||
name = "test-group" | ||
role { | ||
role_name = "reader" | ||
scope = "account" | ||
} | ||
} | ||
resource "selectel_iam_group_membership_v1" "membership_tf_acc_test_1" { | ||
group_id = selectel_iam_group_v1.group_tf_acc_test_1.id | ||
user_ids = [ | ||
selectel_iam_serviceuser_v1.serviceuser_tf_acc_test_1.id, | ||
selectel_iam_serviceuser_v1.serviceuser_tf_acc_test_2.id | ||
] | ||
} | ||
` | ||
} |
Oops, something went wrong.