forked from hashicorp/terraform
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Users - Groups - Roles - Inline policies for the above three - Instance profiles - Managed policies - Access keys This is most of the data types provided by IAM. There are a few things missing, but the functionality here is probably sufficient for 95% of the cases. Makes a dent in hashicorp#28.
- Loading branch information
Phil Frost
committed
Apr 29, 2015
1 parent
f6979cd
commit e448a40
Showing
16 changed files
with
1,459 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/awslabs/aws-sdk-go/aws" | ||
"github.com/awslabs/aws-sdk-go/service/iam" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsIamAccessKey() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsIamAccessKeyCreate, | ||
Read: resourceAwsIamAccessKeyRead, | ||
Delete: resourceAwsIamAccessKeyDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"user": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"status": &schema.Schema{ | ||
Type: schema.TypeString, | ||
// this could be settable, but goamz does not support the | ||
// UpdateAccessKey API yet. | ||
Computed: true, | ||
}, | ||
"secret": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsIamAccessKeyCreate(d *schema.ResourceData, meta interface{}) error { | ||
iamconn := meta.(*AWSClient).iamconn | ||
|
||
request := &iam.CreateAccessKeyInput{ | ||
UserName: aws.String(d.Get("user").(string)), | ||
} | ||
|
||
createResp, err := iamconn.CreateAccessKey(request) | ||
if err != nil { | ||
return fmt.Errorf( | ||
"Error creating access key for user %s: %s", | ||
*request.UserName, | ||
err, | ||
) | ||
} | ||
|
||
if err := d.Set("secret", createResp.AccessKey.SecretAccessKey); err != nil { | ||
return err | ||
} | ||
return resourceAwsIamAccessKeyReadResult(d, &iam.AccessKeyMetadata{ | ||
AccessKeyID: createResp.AccessKey.AccessKeyID, | ||
CreateDate: createResp.AccessKey.CreateDate, | ||
Status: createResp.AccessKey.Status, | ||
UserName: createResp.AccessKey.UserName, | ||
}) | ||
} | ||
|
||
func resourceAwsIamAccessKeyRead(d *schema.ResourceData, meta interface{}) error { | ||
iamconn := meta.(*AWSClient).iamconn | ||
|
||
request := &iam.ListAccessKeysInput{ | ||
UserName: aws.String(d.Get("user").(string)), | ||
} | ||
|
||
getResp, err := iamconn.ListAccessKeys(request) | ||
if err != nil { | ||
if iamerr, ok := err.(aws.APIError); ok && iamerr.Code == "NoSuchEntity" { // XXX TEST ME | ||
// the user does not exist, so the key can't exist. | ||
d.SetId("") | ||
return nil | ||
} | ||
return fmt.Errorf("Error reading IAM acces key: %s", err) | ||
} | ||
|
||
for _, key := range getResp.AccessKeyMetadata { | ||
if key.AccessKeyID != nil && *key.AccessKeyID == d.Id() { | ||
return resourceAwsIamAccessKeyReadResult(d, key) | ||
} | ||
} | ||
|
||
// Guess the key isn't around anymore. | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
func resourceAwsIamAccessKeyReadResult(d *schema.ResourceData, key *iam.AccessKeyMetadata) error { | ||
d.SetId(*key.AccessKeyID) | ||
if err := d.Set("user", key.UserName); err != nil { | ||
return err | ||
} | ||
if err := d.Set("status", key.Status); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func resourceAwsIamAccessKeyDelete(d *schema.ResourceData, meta interface{}) error { | ||
iamconn := meta.(*AWSClient).iamconn | ||
|
||
request := &iam.DeleteAccessKeyInput{ | ||
AccessKeyID: aws.String(d.Id()), | ||
UserName: aws.String(d.Get("user").(string)), | ||
} | ||
|
||
if _, err := iamconn.DeleteAccessKey(request); err != nil { | ||
return fmt.Errorf("Error deleting access key %s: %s", d.Id(), err) | ||
} | ||
return nil | ||
} |
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,106 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/awslabs/aws-sdk-go/aws" | ||
"github.com/awslabs/aws-sdk-go/service/iam" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsIamGroup() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsIamGroupCreate, | ||
Read: resourceAwsIamGroupRead, | ||
// TODO | ||
//Update: resourceAwsIamGroupUpdate, | ||
Delete: resourceAwsIamGroupDelete, | ||
|
||
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, | ||
ForceNew: true, | ||
}, | ||
"path": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "/", | ||
ForceNew: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsIamGroupCreate(d *schema.ResourceData, meta interface{}) error { | ||
iamconn := meta.(*AWSClient).iamconn | ||
name := d.Get("name").(string) | ||
|
||
request := &iam.CreateGroupInput{ | ||
Path: aws.String(d.Get("path").(string)), | ||
GroupName: aws.String(name), | ||
} | ||
|
||
createResp, err := iamconn.CreateGroup(request) | ||
if err != nil { | ||
return fmt.Errorf("Error creating IAM Group %s: %s", name, err) | ||
} | ||
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.(aws.APIError); 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 { | ||
d.SetId(*group.GroupName) | ||
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 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 | ||
} |
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,110 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"net/url" | ||
"strings" | ||
|
||
"github.com/awslabs/aws-sdk-go/aws" | ||
"github.com/awslabs/aws-sdk-go/service/iam" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsIamGroupPolicy() *schema.Resource { | ||
return &schema.Resource{ | ||
// PutGroupPolicy API is idempotent, so these can be the same. | ||
Create: resourceAwsIamGroupPolicyPut, | ||
Update: resourceAwsIamGroupPolicyPut, | ||
|
||
Read: resourceAwsIamGroupPolicyRead, | ||
Delete: resourceAwsIamGroupPolicyDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"policy": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"group": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsIamGroupPolicyPut(d *schema.ResourceData, meta interface{}) error { | ||
iamconn := meta.(*AWSClient).iamconn | ||
|
||
request := &iam.PutGroupPolicyInput{ | ||
GroupName: aws.String(d.Get("group").(string)), | ||
PolicyName: aws.String(d.Get("name").(string)), | ||
PolicyDocument: aws.String(d.Get("policy").(string)), | ||
} | ||
|
||
if _, err := iamconn.PutGroupPolicy(request); err != nil { | ||
return fmt.Errorf("Error putting IAM group policy %s: %s", *request.PolicyName, err) | ||
} | ||
|
||
d.SetId(fmt.Sprintf("%s:%s", *request.GroupName, *request.PolicyName)) | ||
return nil | ||
} | ||
|
||
func resourceAwsIamGroupPolicyRead(d *schema.ResourceData, meta interface{}) error { | ||
iamconn := meta.(*AWSClient).iamconn | ||
|
||
group, name := resourceAwsIamGroupPolicyParseId(d) | ||
|
||
request := &iam.GetGroupPolicyInput{ | ||
PolicyName: aws.String(name), | ||
GroupName: aws.String(group), | ||
} | ||
|
||
getResp, err := iamconn.GetGroupPolicy(request) | ||
if err != nil { | ||
if iamerr, ok := err.(aws.APIError); ok && iamerr.Code == "NoSuchEntity" { // XXX test me | ||
d.SetId("") | ||
return nil | ||
} | ||
return fmt.Errorf("Error reading IAM policy %s from group %s: %s", name, group, err) | ||
} | ||
|
||
if getResp.PolicyDocument == nil { | ||
return fmt.Errorf("GetGroupPolicy returned a nil policy document") | ||
} | ||
|
||
policy, err := url.QueryUnescape(*getResp.PolicyDocument) | ||
if err != nil { | ||
return err | ||
} | ||
return d.Set("policy", policy) | ||
} | ||
|
||
func resourceAwsIamGroupPolicyDelete(d *schema.ResourceData, meta interface{}) error { | ||
iamconn := meta.(*AWSClient).iamconn | ||
|
||
group, name := resourceAwsIamGroupPolicyParseId(d) | ||
|
||
request := &iam.DeleteGroupPolicyInput{ | ||
PolicyName: aws.String(name), | ||
GroupName: aws.String(group), | ||
} | ||
|
||
if _, err := iamconn.DeleteGroupPolicy(request); err != nil { | ||
return fmt.Errorf("Error deleting IAM group policy %s: %s", d.Id(), err) | ||
} | ||
return nil | ||
} | ||
|
||
func resourceAwsIamGroupPolicyParseId(d *schema.ResourceData) (groupName, policyName string) { | ||
parts := strings.SplitN(d.Id(), ":", 2) | ||
groupName = parts[0] | ||
policyName = parts[1] | ||
return | ||
} |
Oops, something went wrong.
e448a40
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my hero!