2015-04-26 03:53:21 +02:00
|
|
|
package aws
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"time"
|
|
|
|
|
2015-06-03 20:36:57 +02:00
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
|
|
"github.com/aws/aws-sdk-go/service/elasticache"
|
2015-04-26 03:53:21 +02:00
|
|
|
"github.com/hashicorp/terraform/helper/resource"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
|
|
)
|
|
|
|
|
|
|
|
func resourceAwsElasticacheSecurityGroup() *schema.Resource {
|
|
|
|
return &schema.Resource{
|
|
|
|
Create: resourceAwsElasticacheSecurityGroupCreate,
|
|
|
|
Read: resourceAwsElasticacheSecurityGroupRead,
|
|
|
|
Delete: resourceAwsElasticacheSecurityGroupDelete,
|
|
|
|
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"description": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
"name": &schema.Schema{
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
"security_group_names": &schema.Schema{
|
|
|
|
Type: schema.TypeSet,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
2016-02-08 00:51:26 +01:00
|
|
|
Set: schema.HashString,
|
2015-04-26 03:53:21 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceAwsElasticacheSecurityGroupCreate(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
conn := meta.(*AWSClient).elasticacheconn
|
|
|
|
|
|
|
|
name := d.Get("name").(string)
|
|
|
|
desc := d.Get("description").(string)
|
|
|
|
nameSet := d.Get("security_group_names").(*schema.Set)
|
|
|
|
|
|
|
|
names := make([]string, nameSet.Len())
|
|
|
|
for i, name := range nameSet.List() {
|
|
|
|
names[i] = name.(string)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("[DEBUG] Cache security group create: name: %s, description: %s, security_group_names: %v", name, desc, names)
|
|
|
|
res, err := conn.CreateCacheSecurityGroup(&elasticache.CreateCacheSecurityGroupInput{
|
|
|
|
Description: aws.String(desc),
|
|
|
|
CacheSecurityGroupName: aws.String(name),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error creating CacheSecurityGroup: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, n := range names {
|
|
|
|
log.Printf("[DEBUG] Authorize cache security group ingress name: %v, ec2 security group name: %v", name, n)
|
|
|
|
_, err = conn.AuthorizeCacheSecurityGroupIngress(&elasticache.AuthorizeCacheSecurityGroupIngressInput{
|
|
|
|
CacheSecurityGroupName: aws.String(name),
|
|
|
|
EC2SecurityGroupName: aws.String(n),
|
2015-08-17 20:27:16 +02:00
|
|
|
EC2SecurityGroupOwnerId: aws.String(*res.CacheSecurityGroup.OwnerId),
|
2015-04-26 03:53:21 +02:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("[ERROR] Failed to authorize: %v", err)
|
|
|
|
_, err := conn.DeleteCacheSecurityGroup(&elasticache.DeleteCacheSecurityGroupInput{
|
|
|
|
CacheSecurityGroupName: aws.String(d.Id()),
|
|
|
|
})
|
|
|
|
log.Printf("[ERROR] Revert cache security group: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
d.SetId(name)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceAwsElasticacheSecurityGroupRead(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
conn := meta.(*AWSClient).elasticacheconn
|
|
|
|
req := &elasticache.DescribeCacheSecurityGroupsInput{
|
|
|
|
CacheSecurityGroupName: aws.String(d.Get("name").(string)),
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := conn.DescribeCacheSecurityGroups(req)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if len(res.CacheSecurityGroups) == 0 {
|
|
|
|
return fmt.Errorf("Error missing %v", d.Get("name"))
|
|
|
|
}
|
|
|
|
|
|
|
|
var group *elasticache.CacheSecurityGroup
|
|
|
|
for _, g := range res.CacheSecurityGroups {
|
|
|
|
log.Printf("[DEBUG] CacheSecurityGroupName: %v, id: %v", g.CacheSecurityGroupName, d.Id())
|
|
|
|
if *g.CacheSecurityGroupName == d.Id() {
|
|
|
|
group = g
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if group == nil {
|
|
|
|
return fmt.Errorf("Error retrieving cache security group: %v", res)
|
|
|
|
}
|
|
|
|
|
|
|
|
d.Set("name", group.CacheSecurityGroupName)
|
|
|
|
d.Set("description", group.Description)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceAwsElasticacheSecurityGroupDelete(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
conn := meta.(*AWSClient).elasticacheconn
|
|
|
|
|
|
|
|
log.Printf("[DEBUG] Cache security group delete: %s", d.Id())
|
|
|
|
|
|
|
|
return resource.Retry(5*time.Minute, func() error {
|
|
|
|
_, err := conn.DeleteCacheSecurityGroup(&elasticache.DeleteCacheSecurityGroupInput{
|
|
|
|
CacheSecurityGroupName: aws.String(d.Id()),
|
|
|
|
})
|
|
|
|
if err != nil {
|
2015-05-20 13:21:23 +02:00
|
|
|
apierr, ok := err.(awserr.Error)
|
2015-04-26 03:53:21 +02:00
|
|
|
if !ok {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
log.Printf("[DEBUG] APIError.Code: %v", apierr.Code)
|
2015-05-20 13:21:23 +02:00
|
|
|
switch apierr.Code() {
|
2015-04-26 03:53:21 +02:00
|
|
|
case "InvalidCacheSecurityGroupState":
|
|
|
|
return err
|
|
|
|
case "DependencyViolation":
|
|
|
|
// If it is a dependency violation, we want to retry
|
|
|
|
return err
|
|
|
|
default:
|
|
|
|
return resource.RetryError{Err: err}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|