github.com/erriapo/terraform@v0.6.12-0.20160203182612-0340ea72354f/builtin/providers/aws/resource_aws_kinesis_stream.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/aws/awserr"
    10  	"github.com/aws/aws-sdk-go/service/kinesis"
    11  	"github.com/hashicorp/terraform/helper/resource"
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  )
    14  
    15  func resourceAwsKinesisStream() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceAwsKinesisStreamCreate,
    18  		Read:   resourceAwsKinesisStreamRead,
    19  		Update: resourceAwsKinesisStreamUpdate,
    20  		Delete: resourceAwsKinesisStreamDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"name": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  
    29  			"shard_count": &schema.Schema{
    30  				Type:     schema.TypeInt,
    31  				Required: true,
    32  				ForceNew: true,
    33  			},
    34  
    35  			"arn": &schema.Schema{
    36  				Type:     schema.TypeString,
    37  				Optional: true,
    38  				Computed: true,
    39  			},
    40  			"tags": tagsSchema(),
    41  		},
    42  	}
    43  }
    44  
    45  func resourceAwsKinesisStreamCreate(d *schema.ResourceData, meta interface{}) error {
    46  	conn := meta.(*AWSClient).kinesisconn
    47  	sn := d.Get("name").(string)
    48  	createOpts := &kinesis.CreateStreamInput{
    49  		ShardCount: aws.Int64(int64(d.Get("shard_count").(int))),
    50  		StreamName: aws.String(sn),
    51  	}
    52  
    53  	_, err := conn.CreateStream(createOpts)
    54  	if err != nil {
    55  		if awsErr, ok := err.(awserr.Error); ok {
    56  			return fmt.Errorf("[WARN] Error creating Kinesis Stream: \"%s\", code: \"%s\"", awsErr.Message(), awsErr.Code())
    57  		}
    58  		return err
    59  	}
    60  
    61  	stateConf := &resource.StateChangeConf{
    62  		Pending:    []string{"CREATING"},
    63  		Target:     []string{"ACTIVE"},
    64  		Refresh:    streamStateRefreshFunc(conn, sn),
    65  		Timeout:    5 * time.Minute,
    66  		Delay:      10 * time.Second,
    67  		MinTimeout: 3 * time.Second,
    68  	}
    69  
    70  	streamRaw, err := stateConf.WaitForState()
    71  	if err != nil {
    72  		return fmt.Errorf(
    73  			"Error waiting for Kinesis Stream (%s) to become active: %s",
    74  			sn, err)
    75  	}
    76  
    77  	s := streamRaw.(kinesisStreamState)
    78  	d.SetId(s.arn)
    79  	d.Set("arn", s.arn)
    80  	d.Set("shard_count", s.shardCount)
    81  
    82  	return resourceAwsKinesisStreamUpdate(d, meta)
    83  }
    84  
    85  func resourceAwsKinesisStreamUpdate(d *schema.ResourceData, meta interface{}) error {
    86  	conn := meta.(*AWSClient).kinesisconn
    87  
    88  	d.Partial(true)
    89  	if err := setTagsKinesis(conn, d); err != nil {
    90  		return err
    91  	}
    92  
    93  	d.SetPartial("tags")
    94  	d.Partial(false)
    95  
    96  	return resourceAwsKinesisStreamRead(d, meta)
    97  }
    98  
    99  func resourceAwsKinesisStreamRead(d *schema.ResourceData, meta interface{}) error {
   100  	conn := meta.(*AWSClient).kinesisconn
   101  	sn := d.Get("name").(string)
   102  
   103  	state, err := readKinesisStreamState(conn, sn)
   104  	if err != nil {
   105  		if awsErr, ok := err.(awserr.Error); ok {
   106  			if awsErr.Code() == "ResourceNotFoundException" {
   107  				d.SetId("")
   108  				return nil
   109  			}
   110  			return fmt.Errorf("[WARN] Error reading Kinesis Stream: \"%s\", code: \"%s\"", awsErr.Message(), awsErr.Code())
   111  		}
   112  		return err
   113  
   114  	}
   115  	d.Set("arn", state.arn)
   116  	d.Set("shard_count", state.shardCount)
   117  
   118  	// set tags
   119  	describeTagsOpts := &kinesis.ListTagsForStreamInput{
   120  		StreamName: aws.String(sn),
   121  	}
   122  	tagsResp, err := conn.ListTagsForStream(describeTagsOpts)
   123  	if err != nil {
   124  		log.Printf("[DEBUG] Error retrieving tags for Stream: %s. %s", sn, err)
   125  	} else {
   126  		d.Set("tags", tagsToMapKinesis(tagsResp.Tags))
   127  	}
   128  
   129  	return nil
   130  }
   131  
   132  func resourceAwsKinesisStreamDelete(d *schema.ResourceData, meta interface{}) error {
   133  	conn := meta.(*AWSClient).kinesisconn
   134  	sn := d.Get("name").(string)
   135  	_, err := conn.DeleteStream(&kinesis.DeleteStreamInput{
   136  		StreamName: aws.String(sn),
   137  	})
   138  
   139  	if err != nil {
   140  		return err
   141  	}
   142  
   143  	stateConf := &resource.StateChangeConf{
   144  		Pending:    []string{"DELETING"},
   145  		Target:     []string{"DESTROYED"},
   146  		Refresh:    streamStateRefreshFunc(conn, sn),
   147  		Timeout:    5 * time.Minute,
   148  		Delay:      10 * time.Second,
   149  		MinTimeout: 3 * time.Second,
   150  	}
   151  
   152  	_, err = stateConf.WaitForState()
   153  	if err != nil {
   154  		return fmt.Errorf(
   155  			"Error waiting for Stream (%s) to be destroyed: %s",
   156  			sn, err)
   157  	}
   158  
   159  	d.SetId("")
   160  	return nil
   161  }
   162  
   163  type kinesisStreamState struct {
   164  	arn        string
   165  	status     string
   166  	shardCount int
   167  }
   168  
   169  func readKinesisStreamState(conn *kinesis.Kinesis, sn string) (kinesisStreamState, error) {
   170  	describeOpts := &kinesis.DescribeStreamInput{
   171  		StreamName: aws.String(sn),
   172  	}
   173  
   174  	var state kinesisStreamState
   175  	err := conn.DescribeStreamPages(describeOpts, func(page *kinesis.DescribeStreamOutput, last bool) (shouldContinue bool) {
   176  		state.arn = aws.StringValue(page.StreamDescription.StreamARN)
   177  		state.status = aws.StringValue(page.StreamDescription.StreamStatus)
   178  		state.shardCount += len(page.StreamDescription.Shards)
   179  		return !last
   180  	})
   181  	return state, err
   182  }
   183  
   184  func streamStateRefreshFunc(conn *kinesis.Kinesis, sn string) resource.StateRefreshFunc {
   185  	return func() (interface{}, string, error) {
   186  		state, err := readKinesisStreamState(conn, sn)
   187  		if err != nil {
   188  			if awsErr, ok := err.(awserr.Error); ok {
   189  				if awsErr.Code() == "ResourceNotFoundException" {
   190  					return 42, "DESTROYED", nil
   191  				}
   192  				return nil, awsErr.Code(), err
   193  			}
   194  			return nil, "failed", err
   195  		}
   196  
   197  		return state, state.status, nil
   198  	}
   199  }