From f31891fa5eb369cc89e25630a58c38291c3fa073 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Mon, 8 Jun 2015 11:17:15 -0500 Subject: [PATCH] provider/aws: Add IAMGroupMembership resource bare bones implementation of a Group Membership resource --- builtin/providers/aws/provider.go | 1 + .../aws/resource_aws_iam_group_membership.go | 93 ++++++++++++++ .../resource_aws_iam_group_membership_test.go | 120 ++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_iam_group_membership.go create mode 100644 builtin/providers/aws/resource_aws_iam_group_membership_test.go diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index de2d9becc..5a7e49c99 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -103,6 +103,7 @@ func Provider() terraform.ResourceProvider { "aws_iam_access_key": resourceAwsIamAccessKey(), "aws_iam_group_policy": resourceAwsIamGroupPolicy(), "aws_iam_group": resourceAwsIamGroup(), + "aws_iam_group_membership": resourceAwsIamGroupMembership(), "aws_iam_instance_profile": resourceAwsIamInstanceProfile(), "aws_iam_policy": resourceAwsIamPolicy(), "aws_iam_role_policy": resourceAwsIamRolePolicy(), diff --git a/builtin/providers/aws/resource_aws_iam_group_membership.go b/builtin/providers/aws/resource_aws_iam_group_membership.go new file mode 100644 index 000000000..21d8f8733 --- /dev/null +++ b/builtin/providers/aws/resource_aws_iam_group_membership.go @@ -0,0 +1,93 @@ +package aws + +import ( + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iam" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsIamGroupMembership() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsIamGroupMembershipCreate, + Read: resourceAwsIamGroupMembershipRead, + //Update: resourceAwsIamGroupMembershipUpdate, + Delete: resourceAwsIamGroupMembershipDelete, + + Schema: map[string]*schema.Schema{ + "user_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "group_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceAwsIamGroupMembershipCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).iamconn + + _, err := conn.AddUserToGroup(&iam.AddUserToGroupInput{ + UserName: aws.String(d.Get("user_name").(string)), + GroupName: aws.String(d.Get("group_name").(string)), + }) + + if err != nil { + return err + } + + d.SetId(resource.UniqueId()) + return resourceAwsIamGroupMembershipRead(d, meta) +} + +func resourceAwsIamGroupMembershipRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).iamconn + u := d.Get("user_name").(string) + resp, err := conn.ListGroupsForUser(&iam.ListGroupsForUserInput{ + UserName: aws.String(u), + }) + + if err != nil { + return err + } + + d.Set("user_name", u) + + gn := d.Get("group_name").(string) + var group *iam.Group + for _, g := range resp.Groups { + if gn == *g.GroupName { + group = g + } + } + + if group == nil { + // if not found, set to "" + log.Printf("[DEBUG] Group (%s) not found for User (%s)", u, gn) + d.SetId("") + } + + return nil +} + +func resourceAwsIamGroupMembershipDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).iamconn + _, err := conn.RemoveUserFromGroup(&iam.RemoveUserFromGroupInput{ + UserName: aws.String(d.Get("user_name").(string)), + GroupName: aws.String(d.Get("group_name").(string)), + }) + + if err != nil { + return err + } + + d.SetId("") + return nil +} diff --git a/builtin/providers/aws/resource_aws_iam_group_membership_test.go b/builtin/providers/aws/resource_aws_iam_group_membership_test.go new file mode 100644 index 000000000..41b04ea51 --- /dev/null +++ b/builtin/providers/aws/resource_aws_iam_group_membership_test.go @@ -0,0 +1,120 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iam" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSGroupMembership_basic(t *testing.T) { + var group iam.Group + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSGroupMembershipDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSGroupMemberConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSGroupMembershipExists("aws_iam_group_membership.team", &group), + testAccCheckAWSGroupMembershipAttributes(&group), + ), + }, + }, + }) +} + +func testAccCheckAWSGroupMembershipDestroy(s *terraform.State) error { + iamconn := testAccProvider.Meta().(*AWSClient).iamconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_iam_group_membership" { + continue + } + + // Try to get user + user := rs.Primary.Attributes["user_name"] + group := rs.Primary.Attributes["group_name"] + + resp, err := iamconn.ListGroupsForUser(&iam.ListGroupsForUserInput{ + UserName: aws.String(user), + }) + if err != nil { + // might error here + return err + } + + for _, g := range resp.Groups { + if group == *g.GroupName { + return fmt.Errorf("Error: User (%s) is still a memeber of Group (%s)", user, group) + } + } + + } + + return nil +} + +func testAccCheckAWSGroupMembershipExists(n string, g *iam.Group) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No User name is set") + } + + iamconn := testAccProvider.Meta().(*AWSClient).iamconn + user := rs.Primary.Attributes["user_name"] + gn := rs.Primary.Attributes["group_name"] + + resp, err := iamconn.ListGroupsForUser(&iam.ListGroupsForUserInput{ + UserName: aws.String(user), + }) + if err != nil { + return err + } + + for _, i := range resp.Groups { + if gn == *i.GroupName { + *g = *i + return nil + } + } + + return fmt.Errorf("Error: User (%s) not a member of Group (%s)", user, gn) + } +} + +func testAccCheckAWSGroupMembershipAttributes(group *iam.Group) resource.TestCheckFunc { + return func(s *terraform.State) error { + if *group.GroupName != "test-group" { + return fmt.Errorf("Bad group membership: expected %s, got %s", "test-group-update", *group.GroupName) + } + return nil + } +} + +const testAccAWSGroupMemberConfig = ` +resource "aws_iam_group" "group" { + name = "test-group" + path = "/" +} + +resource "aws_iam_user" "user" { + name = "test-user" + path = "/" +} + +resource "aws_iam_group_membership" "team" { + user_name = "${aws_iam_user.user.name}" + group_name = "${aws_iam_group.group.name}" +} +`