opentofu/builtin/providers/aws/resource_aws_iam_group.go
stack72 79557bca80
provider/aws: Add validation to IAM User and Group Name
This will allow us to catch errors at plan time rather than waiting for
the API to tell us...

Documentation for IAM User NAme Validation -
http://docs.aws.amazon.com/cli/latest/reference/iam/create-user.html

Documentation for IAM Group Name validation -
http://docs.aws.amazon.com/cli/latest/reference/iam/create-group.html

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSIAMGroup_'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2016/10/25 13:18:41 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSIAMGroup_
-timeout 120m
=== RUN   TestAccAWSIAMGroup_importBasic
--- PASS: TestAccAWSIAMGroup_importBasic (13.80s)
=== RUN   TestAccAWSIAMGroup_basic
--- PASS: TestAccAWSIAMGroup_basic (23.30s)
PASS
ok      github.com/hashicorp/terraform/builtin/providers/aws37.121s
```

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSUser_'                                                                 ✚
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2016/10/25 13:22:23 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSUser_ -timeout 120m
=== RUN   TestAccAWSUser_importBasic
--- PASS: TestAccAWSUser_importBasic (14.33s)
=== RUN   TestAccAWSUser_basic
--- PASS: TestAccAWSUser_basic (25.36s)
PASS
ok  	github.com/hashicorp/terraform/builtin/providers/aws	39.710s
```
2016-10-25 13:18:41 +01:00

142 lines
3.6 KiB
Go

package aws
import (
"fmt"
"regexp"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceAwsIamGroup() *schema.Resource {
return &schema.Resource{
Create: resourceAwsIamGroupCreate,
Read: resourceAwsIamGroupRead,
Update: resourceAwsIamGroupUpdate,
Delete: resourceAwsIamGroupDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"arn": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"unique_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAwsIamGroupName,
},
"path": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Default: "/",
},
},
}
}
func resourceAwsIamGroupCreate(d *schema.ResourceData, meta interface{}) error {
iamconn := meta.(*AWSClient).iamconn
name := d.Get("name").(string)
path := d.Get("path").(string)
request := &iam.CreateGroupInput{
Path: aws.String(path),
GroupName: aws.String(name),
}
createResp, err := iamconn.CreateGroup(request)
if err != nil {
return fmt.Errorf("Error creating IAM Group %s: %s", name, err)
}
d.SetId(*createResp.Group.GroupName)
return resourceAwsIamGroupReadResult(d, createResp.Group)
}
func resourceAwsIamGroupRead(d *schema.ResourceData, meta interface{}) error {
iamconn := meta.(*AWSClient).iamconn
request := &iam.GetGroupInput{
GroupName: aws.String(d.Id()),
}
getResp, err := iamconn.GetGroup(request)
if err != nil {
if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading IAM Group %s: %s", d.Id(), err)
}
return resourceAwsIamGroupReadResult(d, getResp.Group)
}
func resourceAwsIamGroupReadResult(d *schema.ResourceData, group *iam.Group) error {
if err := d.Set("name", group.GroupName); err != nil {
return err
}
if err := d.Set("arn", group.Arn); err != nil {
return err
}
if err := d.Set("path", group.Path); err != nil {
return err
}
if err := d.Set("unique_id", group.GroupId); err != nil {
return err
}
return nil
}
func resourceAwsIamGroupUpdate(d *schema.ResourceData, meta interface{}) error {
if d.HasChange("name") || d.HasChange("path") {
iamconn := meta.(*AWSClient).iamconn
on, nn := d.GetChange("name")
_, np := d.GetChange("path")
request := &iam.UpdateGroupInput{
GroupName: aws.String(on.(string)),
NewGroupName: aws.String(nn.(string)),
NewPath: aws.String(np.(string)),
}
_, err := iamconn.UpdateGroup(request)
if err != nil {
return fmt.Errorf("Error updating IAM Group %s: %s", d.Id(), err)
}
return resourceAwsIamGroupRead(d, meta)
}
return nil
}
func resourceAwsIamGroupDelete(d *schema.ResourceData, meta interface{}) error {
iamconn := meta.(*AWSClient).iamconn
request := &iam.DeleteGroupInput{
GroupName: aws.String(d.Id()),
}
if _, err := iamconn.DeleteGroup(request); err != nil {
return fmt.Errorf("Error deleting IAM Group %s: %s", d.Id(), err)
}
return nil
}
func validateAwsIamGroupName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9A-Za-z=,.@-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only alphanumeric characters, hyphens, commas, periods, @ symbols and equals signs allowed in %q: %q",
k, value))
}
return
}