From a5b2437dcf70800cdfbfd6c6e2b1b0763b4528f7 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Thu, 16 Apr 2015 12:01:10 -0500 Subject: [PATCH] provider/aws: Convert Instance to use upstream library --- .../providers/aws/resource_aws_instance.go | 109 +++++++++--------- .../aws/resource_aws_instance_test.go | 39 ++++--- .../aws/resource_aws_launch_configuration.go | 6 +- 3 files changed, 79 insertions(+), 75 deletions(-) diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go index 85a35e41a..69b3a6e8f 100644 --- a/builtin/providers/aws/resource_aws_instance.go +++ b/builtin/providers/aws/resource_aws_instance.go @@ -10,8 +10,8 @@ import ( "strings" "time" - "github.com/hashicorp/aws-sdk-go/aws" - "github.com/hashicorp/aws-sdk-go/gen/ec2" + "github.com/awslabs/aws-sdk-go/aws" + "github.com/awslabs/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -299,7 +299,7 @@ func resourceAwsInstance() *schema.Resource { } func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).ec2conn + conn := meta.(*AWSClient).ec2SDKconn // Figure out user data userData := "" @@ -329,12 +329,12 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } // Build the creation struct - runOpts := &ec2.RunInstancesRequest{ + runOpts := &ec2.RunInstancesInput{ ImageID: aws.String(d.Get("ami").(string)), Placement: placement, InstanceType: aws.String(d.Get("instance_type").(string)), - MaxCount: aws.Integer(1), - MinCount: aws.Integer(1), + MaxCount: aws.Long(int64(1)), + MinCount: aws.Long(int64(1)), UserData: aws.String(userData), EBSOptimized: aws.Boolean(d.Get("ebs_optimized").(bool)), IAMInstanceProfile: iam, @@ -345,7 +345,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { associatePublicIPAddress = v.(bool) } - var groups []string + var groups []*string if v := d.Get("security_groups"); v != nil { // Security group names. // For a nondefault VPC, you must use security group IDs instead. @@ -355,7 +355,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } for _, v := range v.(*schema.Set).List() { str := v.(string) - groups = append(groups, str) + groups = append(groups, aws.String(str)) } } @@ -367,9 +367,9 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { // You also need to attach Security Groups to the NetworkInterface instead of the instance, // to avoid: Network interfaces and an instance-level security groups may not be specified on // the same request - ni := ec2.InstanceNetworkInterfaceSpecification{ + ni := &ec2.InstanceNetworkInterfaceSpecification{ AssociatePublicIPAddress: aws.Boolean(associatePublicIPAddress), - DeviceIndex: aws.Integer(0), + DeviceIndex: aws.Long(int64(0)), SubnetID: aws.String(subnetID), } @@ -379,11 +379,11 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { if v := d.Get("vpc_security_group_ids"); v != nil { for _, v := range v.(*schema.Set).List() { - ni.Groups = append(ni.Groups, v.(string)) + ni.Groups = append(ni.Groups, aws.String(v.(string))) } } - runOpts.NetworkInterfaces = []ec2.InstanceNetworkInterfaceSpecification{ni} + runOpts.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{ni} } else { if subnetID != "" { runOpts.SubnetID = aws.String(subnetID) @@ -401,7 +401,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { if v := d.Get("vpc_security_group_ids"); v != nil { for _, v := range v.(*schema.Set).List() { - runOpts.SecurityGroupIDs = append(runOpts.SecurityGroupIDs, v.(string)) + runOpts.SecurityGroupIDs = append(runOpts.SecurityGroupIDs, aws.String(v.(string))) } } } @@ -410,7 +410,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { runOpts.KeyName = aws.String(v.(string)) } - blockDevices := make([]ec2.BlockDeviceMapping, 0) + blockDevices := make([]*ec2.BlockDeviceMapping, 0) if v, ok := d.GetOk("ebs_block_device"); ok { vL := v.(*schema.Set).List() @@ -425,7 +425,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } if v, ok := bd["volume_size"].(int); ok && v != 0 { - ebs.VolumeSize = aws.Integer(v) + ebs.VolumeSize = aws.Long(int64(v)) } if v, ok := bd["volume_type"].(string); ok && v != "" { @@ -433,10 +433,10 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } if v, ok := bd["iops"].(int); ok && v > 0 { - ebs.IOPS = aws.Integer(v) + ebs.IOPS = aws.Long(int64(v)) } - blockDevices = append(blockDevices, ec2.BlockDeviceMapping{ + blockDevices = append(blockDevices, &ec2.BlockDeviceMapping{ DeviceName: aws.String(bd["device_name"].(string)), EBS: ebs, }) @@ -447,7 +447,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { vL := v.(*schema.Set).List() for _, v := range vL { bd := v.(map[string]interface{}) - blockDevices = append(blockDevices, ec2.BlockDeviceMapping{ + blockDevices = append(blockDevices, &ec2.BlockDeviceMapping{ DeviceName: aws.String(bd["device_name"].(string)), VirtualName: aws.String(bd["virtual_name"].(string)), }) @@ -466,7 +466,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } if v, ok := bd["volume_size"].(int); ok && v != 0 { - ebs.VolumeSize = aws.Integer(v) + ebs.VolumeSize = aws.Long(int64(v)) } if v, ok := bd["volume_type"].(string); ok && v != "" { @@ -474,11 +474,11 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } if v, ok := bd["iops"].(int); ok && v > 0 { - ebs.IOPS = aws.Integer(v) + ebs.IOPS = aws.Long(int64(v)) } - if dn, err := fetchRootDeviceName(d.Get("ami").(string), ec2conn); err == nil { - blockDevices = append(blockDevices, ec2.BlockDeviceMapping{ + if dn, err := fetchRootDeviceName(d.Get("ami").(string), conn); err == nil { + blockDevices = append(blockDevices, &ec2.BlockDeviceMapping{ DeviceName: dn, EBS: ebs, }) @@ -494,12 +494,12 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { // Create the instance log.Printf("[DEBUG] Run configuration: %#v", runOpts) - runResp, err := ec2conn.RunInstances(runOpts) + runResp, err := conn.RunInstances(runOpts) if err != nil { return fmt.Errorf("Error launching source instance: %s", err) } - instance := &runResp.Instances[0] + instance := runResp.Instances[0] log.Printf("[INFO] Instance ID: %s", *instance.InstanceID) // Store the resulting ID so we can look this up later @@ -514,7 +514,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: "running", - Refresh: InstanceStateRefreshFunc(ec2conn, *instance.InstanceID), + Refresh: InstanceStateRefreshFunc(conn, *instance.InstanceID), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, @@ -547,10 +547,10 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).ec2conn + conn := meta.(*AWSClient).ec2SDKconn - resp, err := ec2conn.DescribeInstances(&ec2.DescribeInstancesRequest{ - InstanceIDs: []string{d.Id()}, + resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIDs: []*string{aws.String(d.Id())}, }) if err != nil { // If the instance was not found, return nil so that we can show @@ -570,7 +570,7 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { return nil } - instance := &resp.Reservations[0].Instances[0] + instance := resp.Reservations[0].Instances[0] // If the instance is terminated, then it is gone if *instance.State.Name == "terminated" { @@ -596,7 +596,7 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { d.Set("subnet_id", instance.SubnetID) } d.Set("ebs_optimized", instance.EBSOptimized) - d.Set("tags", tagsToMap(instance.Tags)) + d.Set("tags", tagsToMapSDK(instance.Tags)) // Determine whether we're referring to security groups with // IDs or names. We use a heuristic to figure this out. By default, @@ -636,7 +636,7 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { } } - if err := readBlockDevices(d, instance, ec2conn); err != nil { + if err := readBlockDevices(d, instance, conn); err != nil { return err } @@ -644,12 +644,14 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { } func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).ec2conn + conn := meta.(*AWSClient).ec2SDKconn + + d.Partial(true) // SourceDestCheck can only be set on VPC instances if d.Get("subnet_id").(string) != "" { log.Printf("[INFO] Modifying instance %s", d.Id()) - err := ec2conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeRequest{ + _, err := conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeInput{ InstanceID: aws.String(d.Id()), SourceDestCheck: &ec2.AttributeBooleanValue{ Value: aws.Boolean(d.Get("source_dest_check").(bool)), @@ -663,23 +665,24 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { // TODO(mitchellh): wait for the attributes we modified to // persist the change... - if err := setTags(ec2conn, d); err != nil { + if err := setTagsSDK(conn, d); err != nil { return err } else { d.SetPartial("tags") } + d.Partial(false) - return nil + return resourceAwsInstanceRead(d, meta) } func resourceAwsInstanceDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).ec2conn + conn := meta.(*AWSClient).ec2SDKconn log.Printf("[INFO] Terminating instance: %s", d.Id()) - req := &ec2.TerminateInstancesRequest{ - InstanceIDs: []string{d.Id()}, + req := &ec2.TerminateInstancesInput{ + InstanceIDs: []*string{aws.String(d.Id())}, } - if _, err := ec2conn.TerminateInstances(req); err != nil { + if _, err := conn.TerminateInstances(req); err != nil { return fmt.Errorf("Error terminating instance: %s", err) } @@ -690,7 +693,7 @@ func resourceAwsInstanceDelete(d *schema.ResourceData, meta interface{}) error { stateConf := &resource.StateChangeConf{ Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"}, Target: "terminated", - Refresh: InstanceStateRefreshFunc(ec2conn, d.Id()), + Refresh: InstanceStateRefreshFunc(conn, d.Id()), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, @@ -711,8 +714,8 @@ func resourceAwsInstanceDelete(d *schema.ResourceData, meta interface{}) error { // an EC2 instance. func InstanceStateRefreshFunc(conn *ec2.EC2, instanceID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - resp, err := conn.DescribeInstances(&ec2.DescribeInstancesRequest{ - InstanceIDs: []string{instanceID}, + resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIDs: []*string{aws.String(instanceID)}, }) if err != nil { if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "InvalidInstanceID.NotFound" { @@ -730,13 +733,13 @@ func InstanceStateRefreshFunc(conn *ec2.EC2, instanceID string) resource.StateRe return nil, "", nil } - i := &resp.Reservations[0].Instances[0] + i := resp.Reservations[0].Instances[0] return i, *i.State.Name, nil } } -func readBlockDevices(d *schema.ResourceData, instance *ec2.Instance, ec2conn *ec2.EC2) error { - ibds, err := readBlockDevicesFromInstance(instance, ec2conn) +func readBlockDevices(d *schema.ResourceData, instance *ec2.Instance, conn *ec2.EC2) error { + ibds, err := readBlockDevicesFromInstance(instance, conn) if err != nil { return err } @@ -753,12 +756,12 @@ func readBlockDevices(d *schema.ResourceData, instance *ec2.Instance, ec2conn *e return nil } -func readBlockDevicesFromInstance(instance *ec2.Instance, ec2conn *ec2.EC2) (map[string]interface{}, error) { +func readBlockDevicesFromInstance(instance *ec2.Instance, conn *ec2.EC2) (map[string]interface{}, error) { blockDevices := make(map[string]interface{}) blockDevices["ebs"] = make([]map[string]interface{}, 0) blockDevices["root"] = nil - instanceBlockDevices := make(map[string]ec2.InstanceBlockDeviceMapping) + instanceBlockDevices := make(map[string]*ec2.InstanceBlockDeviceMapping) for _, bd := range instance.BlockDeviceMappings { if bd.EBS != nil { instanceBlockDevices[*(bd.EBS.VolumeID)] = bd @@ -769,14 +772,14 @@ func readBlockDevicesFromInstance(instance *ec2.Instance, ec2conn *ec2.EC2) (map return nil, nil } - volIDs := make([]string, 0, len(instanceBlockDevices)) + volIDs := make([]*string, 0, len(instanceBlockDevices)) for volID := range instanceBlockDevices { - volIDs = append(volIDs, volID) + volIDs = append(volIDs, aws.String(volID)) } // Need to call DescribeVolumes to get volume_size and volume_type for each // EBS block device - volResp, err := ec2conn.DescribeVolumes(&ec2.DescribeVolumesRequest{ + volResp, err := conn.DescribeVolumes(&ec2.DescribeVolumesInput{ VolumeIDs: volIDs, }) if err != nil { @@ -820,19 +823,19 @@ func readBlockDevicesFromInstance(instance *ec2.Instance, ec2conn *ec2.EC2) (map return blockDevices, nil } -func blockDeviceIsRoot(bd ec2.InstanceBlockDeviceMapping, instance *ec2.Instance) bool { +func blockDeviceIsRoot(bd *ec2.InstanceBlockDeviceMapping, instance *ec2.Instance) bool { return (bd.DeviceName != nil && instance.RootDeviceName != nil && *bd.DeviceName == *instance.RootDeviceName) } -func fetchRootDeviceName(ami string, conn *ec2.EC2) (aws.StringValue, error) { +func fetchRootDeviceName(ami string, conn *ec2.EC2) (*string, error) { if ami == "" { return nil, fmt.Errorf("Cannot fetch root device name for blank AMI ID.") } log.Printf("[DEBUG] Describing AMI %q to get root block device name", ami) - req := &ec2.DescribeImagesRequest{ImageIDs: []string{ami}} + req := &ec2.DescribeImagesInput{ImageIDs: []*string{aws.String(ami)}} if res, err := conn.DescribeImages(req); err == nil { if len(res.Images) == 1 { return res.Images[0].RootDeviceName, nil diff --git a/builtin/providers/aws/resource_aws_instance_test.go b/builtin/providers/aws/resource_aws_instance_test.go index d03bb7159..9c3fdb95b 100644 --- a/builtin/providers/aws/resource_aws_instance_test.go +++ b/builtin/providers/aws/resource_aws_instance_test.go @@ -5,8 +5,8 @@ import ( "reflect" "testing" - "github.com/hashicorp/aws-sdk-go/aws" - "github.com/hashicorp/aws-sdk-go/gen/ec2" + "github.com/awslabs/aws-sdk-go/aws" + "github.com/awslabs/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" @@ -41,11 +41,11 @@ func TestAccAWSInstance_normal(t *testing.T) { // Need a resource in this config so the provisioner will be available Config: testAccInstanceConfig_pre, Check: func(*terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).ec2conn + conn := testAccProvider.Meta().(*AWSClient).ec2SDKconn var err error - vol, err = conn.CreateVolume(&ec2.CreateVolumeRequest{ + vol, err = conn.CreateVolume(&ec2.CreateVolumeInput{ AvailabilityZone: aws.String("us-west-2a"), - Size: aws.Integer(5), + Size: aws.Long(int64(5)), }) return err }, @@ -88,8 +88,9 @@ func TestAccAWSInstance_normal(t *testing.T) { resource.TestStep{ Config: testAccInstanceConfig, Check: func(*terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).ec2conn - return conn.DeleteVolume(&ec2.DeleteVolumeRequest{VolumeID: vol.VolumeID}) + conn := testAccProvider.Meta().(*AWSClient).ec2SDKconn + _, err := conn.DeleteVolume(&ec2.DeleteVolumeInput{VolumeID: vol.VolumeID}) + return err }, }, }, @@ -103,7 +104,7 @@ func TestAccAWSInstance_blockDevices(t *testing.T) { return func(*terraform.State) error { // Map out the block devices by name, which should be unique. - blockDevices := make(map[string]ec2.InstanceBlockDeviceMapping) + blockDevices := make(map[string]*ec2.InstanceBlockDeviceMapping) for _, blockDevice := range v.BlockDeviceMappings { blockDevices[*blockDevice.DeviceName] = blockDevice } @@ -286,9 +287,9 @@ func TestAccAWSInstance_tags(t *testing.T) { Config: testAccCheckInstanceConfigTags, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_instance.foo", &v), - testAccCheckTags(&v.Tags, "foo", "bar"), + testAccCheckTagsSDK(&v.Tags, "foo", "bar"), // Guard against regression of https://github.com/hashicorp/terraform/issues/914 - testAccCheckTags(&v.Tags, "#", ""), + testAccCheckTagsSDK(&v.Tags, "#", ""), ), }, @@ -296,8 +297,8 @@ func TestAccAWSInstance_tags(t *testing.T) { Config: testAccCheckInstanceConfigTagsUpdate, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_instance.foo", &v), - testAccCheckTags(&v.Tags, "foo", ""), - testAccCheckTags(&v.Tags, "bar", "baz"), + testAccCheckTagsSDK(&v.Tags, "foo", ""), + testAccCheckTagsSDK(&v.Tags, "bar", "baz"), ), }, }, @@ -363,7 +364,7 @@ func TestAccAWSInstance_associatePublicIPAndPrivateIP(t *testing.T) { } func testAccCheckInstanceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).ec2conn + conn := testAccProvider.Meta().(*AWSClient).ec2SDKconn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_instance" { @@ -371,8 +372,8 @@ func testAccCheckInstanceDestroy(s *terraform.State) error { } // Try to find the resource - resp, err := conn.DescribeInstances(&ec2.DescribeInstancesRequest{ - InstanceIDs: []string{rs.Primary.ID}, + resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIDs: []*string{aws.String(rs.Primary.ID)}, }) if err == nil { if len(resp.Reservations) > 0 { @@ -406,9 +407,9 @@ func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFun return fmt.Errorf("No ID is set") } - conn := testAccProvider.Meta().(*AWSClient).ec2conn - resp, err := conn.DescribeInstances(&ec2.DescribeInstancesRequest{ - InstanceIDs: []string{rs.Primary.ID}, + conn := testAccProvider.Meta().(*AWSClient).ec2SDKconn + resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIDs: []*string{aws.String(rs.Primary.ID)}, }) if err != nil { return err @@ -417,7 +418,7 @@ func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFun return fmt.Errorf("Instance not found") } - *i = resp.Reservations[0].Instances[0] + *i = *resp.Reservations[0].Instances[0] return nil } diff --git a/builtin/providers/aws/resource_aws_launch_configuration.go b/builtin/providers/aws/resource_aws_launch_configuration.go index c80fbd402..0a1315d72 100644 --- a/builtin/providers/aws/resource_aws_launch_configuration.go +++ b/builtin/providers/aws/resource_aws_launch_configuration.go @@ -11,7 +11,7 @@ import ( "github.com/awslabs/aws-sdk-go/aws" "github.com/awslabs/aws-sdk-go/service/autoscaling" - "github.com/hashicorp/aws-sdk-go/gen/ec2" + "github.com/awslabs/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -243,7 +243,7 @@ func resourceAwsLaunchConfiguration() *schema.Resource { func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface{}) error { autoscalingconn := meta.(*AWSClient).autoscalingconn - ec2conn := meta.(*AWSClient).ec2conn + ec2conn := meta.(*AWSClient).ec2SDKconn createLaunchConfigurationOpts := autoscaling.CreateLaunchConfigurationInput{ LaunchConfigurationName: aws.String(d.Get("name").(string)), @@ -394,7 +394,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface func resourceAwsLaunchConfigurationRead(d *schema.ResourceData, meta interface{}) error { autoscalingconn := meta.(*AWSClient).autoscalingconn - ec2conn := meta.(*AWSClient).ec2conn + ec2conn := meta.(*AWSClient).ec2SDKconn describeOpts := autoscaling.DescribeLaunchConfigurationsInput{ LaunchConfigurationNames: []*string{aws.String(d.Id())},