156 lines
3.9 KiB
Go
156 lines
3.9 KiB
Go
|
package aws
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"time"
|
||
|
|
||
|
"github.com/aws/aws-sdk-go/aws"
|
||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||
|
"github.com/aws/aws-sdk-go/service/opsworks"
|
||
|
"github.com/hashicorp/terraform/helper/resource"
|
||
|
"github.com/hashicorp/terraform/helper/schema"
|
||
|
)
|
||
|
|
||
|
func resourceAwsOpsworksPermission() *schema.Resource {
|
||
|
return &schema.Resource{
|
||
|
Create: resourceAwsOpsworksPermissionCreate,
|
||
|
Update: resourceAwsOpsworksPermissionCreate,
|
||
|
Delete: resourceAwsOpsworksPermissionDelete,
|
||
|
Read: resourceAwsOpsworksPermissionRead,
|
||
|
|
||
|
Schema: map[string]*schema.Schema{
|
||
|
"id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Computed: true,
|
||
|
},
|
||
|
"allow_ssh": &schema.Schema{
|
||
|
Type: schema.TypeBool,
|
||
|
Computed: true,
|
||
|
Optional: true,
|
||
|
},
|
||
|
"allow_sudo": &schema.Schema{
|
||
|
Type: schema.TypeBool,
|
||
|
Computed: true,
|
||
|
Optional: true,
|
||
|
},
|
||
|
"user_arn": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Required: true,
|
||
|
},
|
||
|
// one of deny, show, deploy, manage, iam_only
|
||
|
"level": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Computed: true,
|
||
|
Optional: true,
|
||
|
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
||
|
value := v.(string)
|
||
|
|
||
|
expected := [5]string{"deny", "show", "deploy", "manage", "iam_only"}
|
||
|
|
||
|
found := false
|
||
|
for _, b := range expected {
|
||
|
if b == value {
|
||
|
found = true
|
||
|
}
|
||
|
}
|
||
|
if !found {
|
||
|
errors = append(errors, fmt.Errorf(
|
||
|
"%q has to be one of [deny, show, deploy, manage, iam_only]", k))
|
||
|
}
|
||
|
return
|
||
|
},
|
||
|
},
|
||
|
"stack_id": &schema.Schema{
|
||
|
Type: schema.TypeString,
|
||
|
Computed: true,
|
||
|
Optional: true,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func resourceAwsOpsworksPermissionDelete(d *schema.ResourceData, meta interface{}) error {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func resourceAwsOpsworksPermissionRead(d *schema.ResourceData, meta interface{}) error {
|
||
|
client := meta.(*AWSClient).opsworksconn
|
||
|
|
||
|
req := &opsworks.DescribePermissionsInput{
|
||
|
IamUserArn: aws.String(d.Get("user_arn").(string)),
|
||
|
StackId: aws.String(d.Get("stack_id").(string)),
|
||
|
}
|
||
|
|
||
|
log.Printf("[DEBUG] Reading OpsWorks prermissions for: %s on stack: %s", d.Get("user_arn"), d.Get("stack_id"))
|
||
|
|
||
|
resp, err := client.DescribePermissions(req)
|
||
|
if err != nil {
|
||
|
if awserr, ok := err.(awserr.Error); ok {
|
||
|
if awserr.Code() == "ResourceNotFoundException" {
|
||
|
log.Printf("[INFO] Permission not found")
|
||
|
d.SetId("")
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
found := false
|
||
|
id := ""
|
||
|
for _, permission := range resp.Permissions {
|
||
|
id = *permission.IamUserArn + *permission.StackId
|
||
|
|
||
|
if d.Get("user_arn").(string)+d.Get("stack_id").(string) == id {
|
||
|
found = true
|
||
|
d.SetId(id)
|
||
|
d.Set("id", id)
|
||
|
d.Set("allow_ssh", permission.AllowSudo)
|
||
|
d.Set("allow_sodo", permission.AllowSudo)
|
||
|
d.Set("user_arn", permission.IamUserArn)
|
||
|
d.Set("stack_id", permission.StackId)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if false == found {
|
||
|
d.SetId("")
|
||
|
log.Printf("[INFO] The correct permission could not be found for: %s on stack: %s", d.Get("user_arn"), d.Get("stack_id"))
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func resourceAwsOpsworksPermissionCreate(d *schema.ResourceData, meta interface{}) error {
|
||
|
client := meta.(*AWSClient).opsworksconn
|
||
|
|
||
|
req := &opsworks.SetPermissionInput{
|
||
|
AllowSudo: aws.Bool(d.Get("allow_sudo").(bool)),
|
||
|
AllowSsh: aws.Bool(d.Get("allow_ssh").(bool)),
|
||
|
IamUserArn: aws.String(d.Get("user_arn").(string)),
|
||
|
StackId: aws.String(d.Get("stack_id").(string)),
|
||
|
}
|
||
|
|
||
|
var resp *opsworks.SetPermissionOutput
|
||
|
err := resource.Retry(2*time.Minute, func() *resource.RetryError {
|
||
|
var cerr error
|
||
|
resp, cerr = client.SetPermission(req)
|
||
|
if cerr != nil {
|
||
|
log.Printf("[INFO] client error")
|
||
|
if opserr, ok := cerr.(awserr.Error); ok {
|
||
|
// XXX: handle errors
|
||
|
log.Printf("[ERROR] OpsWorks error: %s message: %s", opserr.Code(), opserr.Message())
|
||
|
return resource.RetryableError(cerr)
|
||
|
}
|
||
|
return resource.NonRetryableError(cerr)
|
||
|
}
|
||
|
return nil
|
||
|
})
|
||
|
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return resourceAwsOpsworksPermissionRead(d, meta)
|
||
|
}
|