github.com/ottenhoff/terraform@v0.7.0-rc1.0.20160607213102-ac2d195cc560/builtin/providers/aws/resource_aws_redshift_subnet_group.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"regexp"
     7  	"time"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/awserr"
    11  	"github.com/aws/aws-sdk-go/service/redshift"
    12  	"github.com/hashicorp/terraform/helper/resource"
    13  	"github.com/hashicorp/terraform/helper/schema"
    14  )
    15  
    16  func resourceAwsRedshiftSubnetGroup() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceAwsRedshiftSubnetGroupCreate,
    19  		Read:   resourceAwsRedshiftSubnetGroupRead,
    20  		Update: resourceAwsRedshiftSubnetGroupUpdate,
    21  		Delete: resourceAwsRedshiftSubnetGroupDelete,
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"name": &schema.Schema{
    25  				Type:         schema.TypeString,
    26  				ForceNew:     true,
    27  				Required:     true,
    28  				ValidateFunc: validateRedshiftSubnetGroupName,
    29  			},
    30  
    31  			"description": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				Optional: true,
    34  				Default:  "Managed by Terraform",
    35  			},
    36  
    37  			"subnet_ids": &schema.Schema{
    38  				Type:     schema.TypeSet,
    39  				Required: true,
    40  				Elem:     &schema.Schema{Type: schema.TypeString},
    41  				Set:      schema.HashString,
    42  			},
    43  		},
    44  	}
    45  }
    46  
    47  func resourceAwsRedshiftSubnetGroupCreate(d *schema.ResourceData, meta interface{}) error {
    48  	conn := meta.(*AWSClient).redshiftconn
    49  
    50  	subnetIdsSet := d.Get("subnet_ids").(*schema.Set)
    51  	subnetIds := make([]*string, subnetIdsSet.Len())
    52  	for i, subnetId := range subnetIdsSet.List() {
    53  		subnetIds[i] = aws.String(subnetId.(string))
    54  	}
    55  
    56  	createOpts := redshift.CreateClusterSubnetGroupInput{
    57  		ClusterSubnetGroupName: aws.String(d.Get("name").(string)),
    58  		Description:            aws.String(d.Get("description").(string)),
    59  		SubnetIds:              subnetIds,
    60  	}
    61  
    62  	log.Printf("[DEBUG] Create Redshift Subnet Group: %#v", createOpts)
    63  	_, err := conn.CreateClusterSubnetGroup(&createOpts)
    64  	if err != nil {
    65  		return fmt.Errorf("Error creating Redshift Subnet Group: %s", err)
    66  	}
    67  
    68  	d.SetId(*createOpts.ClusterSubnetGroupName)
    69  	log.Printf("[INFO] Redshift Subnet Group ID: %s", d.Id())
    70  	return resourceAwsRedshiftSubnetGroupRead(d, meta)
    71  }
    72  
    73  func resourceAwsRedshiftSubnetGroupRead(d *schema.ResourceData, meta interface{}) error {
    74  	conn := meta.(*AWSClient).redshiftconn
    75  
    76  	describeOpts := redshift.DescribeClusterSubnetGroupsInput{
    77  		ClusterSubnetGroupName: aws.String(d.Id()),
    78  	}
    79  
    80  	describeResp, err := conn.DescribeClusterSubnetGroups(&describeOpts)
    81  	if err != nil {
    82  		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "ClusterSubnetGroupNotFoundFault" {
    83  			log.Printf("[INFO] Redshift Subnet Group: %s was not found", d.Id())
    84  			d.SetId("")
    85  			return nil
    86  		}
    87  		return err
    88  	}
    89  
    90  	if len(describeResp.ClusterSubnetGroups) == 0 {
    91  		return fmt.Errorf("Unable to find Redshift Subnet Group: %#v", describeResp.ClusterSubnetGroups)
    92  	}
    93  
    94  	d.Set("name", d.Id())
    95  	d.Set("description", describeResp.ClusterSubnetGroups[0].Description)
    96  	d.Set("subnet_ids", subnetIdsToSlice(describeResp.ClusterSubnetGroups[0].Subnets))
    97  
    98  	return nil
    99  }
   100  
   101  func resourceAwsRedshiftSubnetGroupUpdate(d *schema.ResourceData, meta interface{}) error {
   102  	conn := meta.(*AWSClient).redshiftconn
   103  	if d.HasChange("subnet_ids") {
   104  		_, n := d.GetChange("subnet_ids")
   105  		if n == nil {
   106  			n = new(schema.Set)
   107  		}
   108  		ns := n.(*schema.Set)
   109  
   110  		var sIds []*string
   111  		for _, s := range ns.List() {
   112  			sIds = append(sIds, aws.String(s.(string)))
   113  		}
   114  
   115  		_, err := conn.ModifyClusterSubnetGroup(&redshift.ModifyClusterSubnetGroupInput{
   116  			ClusterSubnetGroupName: aws.String(d.Id()),
   117  			SubnetIds:              sIds,
   118  		})
   119  
   120  		if err != nil {
   121  			return err
   122  		}
   123  	}
   124  
   125  	return nil
   126  }
   127  
   128  func resourceAwsRedshiftSubnetGroupDelete(d *schema.ResourceData, meta interface{}) error {
   129  	stateConf := &resource.StateChangeConf{
   130  		Pending:    []string{"pending"},
   131  		Target:     []string{"destroyed"},
   132  		Refresh:    resourceAwsRedshiftSubnetGroupDeleteRefreshFunc(d, meta),
   133  		Timeout:    3 * time.Minute,
   134  		MinTimeout: 1 * time.Second,
   135  	}
   136  	_, err := stateConf.WaitForState()
   137  	return err
   138  }
   139  
   140  func resourceAwsRedshiftSubnetGroupDeleteRefreshFunc(d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc {
   141  	conn := meta.(*AWSClient).redshiftconn
   142  
   143  	return func() (interface{}, string, error) {
   144  
   145  		deleteOpts := redshift.DeleteClusterSubnetGroupInput{
   146  			ClusterSubnetGroupName: aws.String(d.Id()),
   147  		}
   148  
   149  		if _, err := conn.DeleteClusterSubnetGroup(&deleteOpts); err != nil {
   150  			redshiftErr, ok := err.(awserr.Error)
   151  			if !ok {
   152  				return d, "error", err
   153  			}
   154  
   155  			if redshiftErr.Code() != "ClusterSubnetGroupNotFoundFault" {
   156  				return d, "error", err
   157  			}
   158  		}
   159  
   160  		return d, "destroyed", nil
   161  	}
   162  }
   163  
   164  func subnetIdsToSlice(subnetIds []*redshift.Subnet) []string {
   165  	subnetsSlice := make([]string, 0, len(subnetIds))
   166  	for _, s := range subnetIds {
   167  		subnetsSlice = append(subnetsSlice, *s.SubnetIdentifier)
   168  	}
   169  	return subnetsSlice
   170  }
   171  
   172  func validateRedshiftSubnetGroupName(v interface{}, k string) (ws []string, errors []error) {
   173  	value := v.(string)
   174  	if !regexp.MustCompile(`^[0-9a-z-_]+$`).MatchString(value) {
   175  		errors = append(errors, fmt.Errorf(
   176  			"only lowercase alphanumeric characters, hyphens, underscores, and periods allowed in %q", k))
   177  	}
   178  	if len(value) > 255 {
   179  		errors = append(errors, fmt.Errorf(
   180  			"%q cannot be longer than 255 characters", k))
   181  	}
   182  	if regexp.MustCompile(`(?i)^default$`).MatchString(value) {
   183  		errors = append(errors, fmt.Errorf(
   184  			"%q is not allowed as %q", "Default", k))
   185  	}
   186  	return
   187  }