From 07b44a816a3c6a02336cf57ae0dfd17c5173d284 Mon Sep 17 00:00:00 2001 From: David Watson Date: Mon, 16 Feb 2015 16:06:23 +0000 Subject: [PATCH 01/73] Add InstanceGroupManager to GCE. --- builtin/providers/google/config.go | 10 +- builtin/providers/google/operation.go | 48 +++ builtin/providers/google/provider.go | 21 +- ...urce_replicapool_instance_group_manager.go | 319 +++++++++++++++ ...replicapool_instance_group_manager_test.go | 365 ++++++++++++++++++ 5 files changed, 751 insertions(+), 12 deletions(-) create mode 100644 builtin/providers/google/resource_replicapool_instance_group_manager.go create mode 100644 builtin/providers/google/resource_replicapool_instance_group_manager_test.go diff --git a/builtin/providers/google/config.go b/builtin/providers/google/config.go index 009f00092..65c5b26bc 100644 --- a/builtin/providers/google/config.go +++ b/builtin/providers/google/config.go @@ -8,13 +8,13 @@ import ( "os" "code.google.com/p/google-api-go-client/compute/v1" + "code.google.com/p/google-api-go-client/replicapool/v1beta2" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" ) - // Config is the configuration structure used to instantiate the Google // provider. type Config struct { @@ -22,7 +22,8 @@ type Config struct { Project string Region string - clientCompute *compute.Service + clientCompute *compute.Service + clientReplicaPool *replicapool.Service } func (c *Config) loadAndValidate() error { @@ -89,6 +90,11 @@ func (c *Config) loadAndValidate() error { return err } + c.clientReplicaPool, err = replicapool.New(client) + if err != nil { + return err + } + return nil } diff --git a/builtin/providers/google/operation.go b/builtin/providers/google/operation.go index 32bf79a5e..141a7684c 100644 --- a/builtin/providers/google/operation.go +++ b/builtin/providers/google/operation.go @@ -5,6 +5,7 @@ import ( "fmt" "code.google.com/p/google-api-go-client/compute/v1" + "code.google.com/p/google-api-go-client/replicapool/v1beta2" "github.com/hashicorp/terraform/helper/resource" ) @@ -77,3 +78,50 @@ func (e OperationError) Error() string { return buf.String() } + +// Replicapool Operations +type ReplicaPoolOperationWaiter struct { + Service *replicapool.Service + Op *replicapool.Operation + Project string + Region string + Zone string +} + +func (w *ReplicaPoolOperationWaiter) RefreshFunc() resource.StateRefreshFunc { + return func() (interface{}, string, error) { + var op *replicapool.Operation + var err error + + op, err = w.Service.ZoneOperations.Get( + w.Project, w.Zone, w.Op.Name).Do() + + if err != nil { + return nil, "", err + } + + return op, op.Status, nil + } +} + +func (w *ReplicaPoolOperationWaiter) Conf() *resource.StateChangeConf { + return &resource.StateChangeConf{ + Pending: []string{"PENDING", "RUNNING"}, + Target: "DONE", + Refresh: w.RefreshFunc(), + } +} + +// ReplicaPoolOperationError wraps replicapool.OperationError and implements the +// error interface so it can be returned. +type ReplicaPoolOperationError replicapool.OperationError + +func (e ReplicaPoolOperationError) Error() string { + var buf bytes.Buffer + + for _, err := range e.Errors { + buf.WriteString(err.Message + "\n") + } + + return buf.String() +} diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index c63b29402..cf4093aa7 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -29,16 +29,17 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ - "google_compute_address": resourceComputeAddress(), - "google_compute_disk": resourceComputeDisk(), - "google_compute_firewall": resourceComputeFirewall(), - "google_compute_forwarding_rule": resourceComputeForwardingRule(), - "google_compute_http_health_check": resourceComputeHttpHealthCheck(), - "google_compute_instance": resourceComputeInstance(), - "google_compute_instance_template": resourceComputeInstanceTemplate(), - "google_compute_network": resourceComputeNetwork(), - "google_compute_route": resourceComputeRoute(), - "google_compute_target_pool": resourceComputeTargetPool(), + "google_compute_address": resourceComputeAddress(), + "google_compute_disk": resourceComputeDisk(), + "google_compute_firewall": resourceComputeFirewall(), + "google_compute_forwarding_rule": resourceComputeForwardingRule(), + "google_compute_http_health_check": resourceComputeHttpHealthCheck(), + "google_compute_instance": resourceComputeInstance(), + "google_compute_instance_template": resourceComputeInstanceTemplate(), + "google_compute_network": resourceComputeNetwork(), + "google_compute_route": resourceComputeRoute(), + "google_compute_target_pool": resourceComputeTargetPool(), + "google_replicapool_instance_group_manager": resourceReplicaPoolInstanceGroupManager(), }, ConfigureFunc: providerConfigure, diff --git a/builtin/providers/google/resource_replicapool_instance_group_manager.go b/builtin/providers/google/resource_replicapool_instance_group_manager.go new file mode 100644 index 000000000..989be6e24 --- /dev/null +++ b/builtin/providers/google/resource_replicapool_instance_group_manager.go @@ -0,0 +1,319 @@ +package google + +import ( + "fmt" + "log" + "time" + + "code.google.com/p/google-api-go-client/googleapi" + "code.google.com/p/google-api-go-client/replicapool/v1beta2" + + "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceReplicaPoolInstanceGroupManager() *schema.Resource { + return &schema.Resource{ + Create: resourceReplicaPoolInstanceGroupManagerCreate, + Read: resourceReplicaPoolInstanceGroupManagerRead, + Update: resourceReplicaPoolInstanceGroupManagerUpdate, + Delete: resourceReplicaPoolInstanceGroupManagerDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "base_instance_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "current_size": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + }, + + "fingerprint": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "group": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "instance_template": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + + "target_pools": &schema.Schema{ + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: func(v interface{}) int { + return hashcode.String(v.(string)) + }, + }, + + "size": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + + "target_size": &schema.Schema{ + Type: schema.TypeInt, + Computed: true, + }, + + "zone": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "self_link": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func waitOpZone(config *Config, op *replicapool.Operation, zone string, + resource string, action string) (*replicapool.Operation, error) { + + w := &ReplicaPoolOperationWaiter{ + Service: config.clientReplicaPool, + Op: op, + Project: config.Project, + Zone: zone, + } + state := w.Conf() + state.Timeout = 2 * time.Minute + state.MinTimeout = 1 * time.Second + opRaw, err := state.WaitForState() + if err != nil { + return nil, fmt.Errorf("Error waiting for %s to %s: %s", resource, action, err) + } + return opRaw.(*replicapool.Operation), nil +} + +func resourceReplicaPoolInstanceGroupManagerCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + // Get group size + var size int64 + if v, ok := d.GetOk("size"); ok { + size = int64(v.(int)) + } + + // Build the parameter + manager := &replicapool.InstanceGroupManager{ + Name: d.Get("name").(string), + BaseInstanceName: d.Get("base_instance_name").(string), + InstanceTemplate: d.Get("instance_template").(string), + } + + // Set optional fields + if v, ok := d.GetOk("description"); ok { + manager.Description = v.(string) + } + + if attr := d.Get("target_pools").(*schema.Set); attr.Len() > 0 { + var s []string + for _, v := range attr.List() { + s = append(s, v.(string)) + } + manager.TargetPools = s + } + + log.Printf("[DEBUG] InstanceGroupManager insert request: %#v", manager) + op, err := config.clientReplicaPool.InstanceGroupManagers.Insert( + config.Project, d.Get("zone").(string), size, manager).Do() + if err != nil { + return fmt.Errorf("Error creating InstanceGroupManager: %s", err) + } + + // It probably maybe worked, so store the ID now + d.SetId(manager.Name) + + // Wait for the operation to complete + op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "create") + if err != nil { + return err + } + if op.Error != nil { + // The resource didn't actually create + d.SetId("") + // Return the error + return ReplicaPoolOperationError(*op.Error) + } + + return resourceReplicaPoolInstanceGroupManagerRead(d, meta) +} + +func resourceReplicaPoolInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + manager, err := config.clientReplicaPool.InstanceGroupManagers.Get( + config.Project, d.Get("zone").(string), d.Id()).Do() + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + // The resource doesn't exist anymore + d.SetId("") + + return nil + } + + return fmt.Errorf("Error reading instance group manager: %s", err) + } + + // Set computed fields + d.Set("current_size", manager.CurrentSize) + d.Set("fingerprint", manager.Fingerprint) + d.Set("group", manager.Group) + d.Set("target_size", manager.TargetSize) + d.Set("self_link", manager.SelfLink) + + return nil +} +func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + d.Partial(true) + + // If target_pools changes then update + if d.HasChange("target_pools") { + var targetPools []string + if attr := d.Get("target_pools").(*schema.Set); attr.Len() > 0 { + for _, v := range attr.List() { + targetPools = append(targetPools, v.(string)) + } + } + + // Build the parameter + setTargetPools := &replicapool.InstanceGroupManagersSetTargetPoolsRequest{ + Fingerprint: d.Get("fingerprint").(string), + TargetPools: targetPools, + } + + op, err := config.clientReplicaPool.InstanceGroupManagers.SetTargetPools( + config.Project, d.Get("zone").(string), d.Id(), setTargetPools).Do() + if err != nil { + return fmt.Errorf("Error updating InstanceGroupManager: %s", err) + } + + // Wait for the operation to complete + op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update TargetPools") + if err != nil { + return err + } + if op.Error != nil { + return ReplicaPoolOperationError(*op.Error) + } + + d.SetPartial("target_pools") + } + + // If instance_template changes then update + if d.HasChange("instance_template") { + // Build the parameter + setInstanceTemplate := &replicapool.InstanceGroupManagersSetInstanceTemplateRequest{ + InstanceTemplate: d.Get("instance_template").(string), + } + + op, err := config.clientReplicaPool.InstanceGroupManagers.SetInstanceTemplate( + config.Project, d.Get("zone").(string), d.Id(), setInstanceTemplate).Do() + if err != nil { + return fmt.Errorf("Error updating InstanceGroupManager: %s", err) + } + + // Wait for the operation to complete + op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update instance template") + if err != nil { + return err + } + if op.Error != nil { + return ReplicaPoolOperationError(*op.Error) + } + + d.SetPartial("instance_template") + } + + // If size changes trigger a resize + if d.HasChange("size") { + var size int64 + if v, ok := d.GetOk("size"); ok { + size = int64(v.(int)) + } + + op, err := config.clientReplicaPool.InstanceGroupManagers.Resize( + config.Project, d.Get("zone").(string), d.Id(), size).Do() + if err != nil { + return fmt.Errorf("Error updating InstanceGroupManager: %s", err) + } + + // Wait for the operation to complete + op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update size") + if err != nil { + return err + } + if op.Error != nil { + return ReplicaPoolOperationError(*op.Error) + } + + d.SetPartial("size") + } + + d.Partial(false) + + return resourceReplicaPoolInstanceGroupManagerRead(d, meta) +} + +func resourceReplicaPoolInstanceGroupManagerDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + zone := d.Get("zone").(string) + op, err := config.clientReplicaPool.InstanceGroupManagers.Delete(config.Project, zone, d.Id()).Do() + if err != nil { + return fmt.Errorf("Error deleting instance group manager: %s", err) + } + + // Wait for the operation to complete + w := &ReplicaPoolOperationWaiter{ + Service: config.clientReplicaPool, + Op: op, + Project: config.Project, + Zone: d.Get("zone").(string), + } + state := w.Conf() + state.Timeout = 2 * time.Minute + state.MinTimeout = 1 * time.Second + opRaw, err := state.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for InstanceGroupManager to delete: %s", err) + } + op = opRaw.(*replicapool.Operation) + if op.Error != nil { + // The resource didn't actually create + d.SetId("") + + // Return the error + return ReplicaPoolOperationError(*op.Error) + } + + d.SetId("") + return nil +} diff --git a/builtin/providers/google/resource_replicapool_instance_group_manager_test.go b/builtin/providers/google/resource_replicapool_instance_group_manager_test.go new file mode 100644 index 000000000..3ddf0af37 --- /dev/null +++ b/builtin/providers/google/resource_replicapool_instance_group_manager_test.go @@ -0,0 +1,365 @@ +package google + +import ( + "fmt" + "log" + "testing" + + "code.google.com/p/google-api-go-client/replicapool/v1beta2" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccInstanceGroupManager_basic(t *testing.T) { + var manager replicapool.InstanceGroupManager + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceGroupManagerDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccInstanceGroupManager_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceGroupManagerExists( + "google_replicapool_instance_group_manager.foobar", &manager), + ), + }, + }, + }) +} + +func TestAccInstanceGroupManager_update(t *testing.T) { + var manager replicapool.InstanceGroupManager + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceGroupManagerDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccInstanceGroupManager_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceGroupManagerExists( + "google_replicapool_instance_group_manager.foobar", &manager), + ), + }, + resource.TestStep{ + Config: testAccInstanceGroupManager_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceGroupManagerExists( + "google_replicapool_instance_group_manager.foobar", &manager), + ), + }, + resource.TestStep{ + Config: testAccInstanceGroupManager_update2, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceGroupManagerExists( + "google_replicapool_instance_group_manager.foobar", &manager), + testAccCheckInstanceGroupManagerUpdated( + "google_replicapool_instance_group_manager.foobar", 3, + "google_compute_target_pool.foobaz", "terraform-test-foobaz"), + ), + }, + }, + }) +} + +func testAccCheckInstanceGroupManagerDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "google_replicapool_instance_group_manager" { + continue + } + _, err := config.clientReplicaPool.InstanceGroupManagers.Get( + config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + if err != nil { + return fmt.Errorf("InstanceGroupManager still exists") + } + } + + return nil +} + +func testAccCheckInstanceGroupManagerExists(n string, manager *replicapool.InstanceGroupManager) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + + found, err := config.clientReplicaPool.InstanceGroupManagers.Get( + config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + if err != nil { + return err + } + + if found.Name != rs.Primary.ID { + return fmt.Errorf("InstanceGroupManager not found") + } + + *manager = *found + + return nil + } +} + +func testAccCheckInstanceGroupManagerUpdated(n string, size int64, targetPool string, template string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + log.Printf("[DEBUG] XXXXXXXXXXXXXXXXXXXXXXXX Manager Test: %#v", rs) + + config := testAccProvider.Meta().(*Config) + + manager, err := config.clientReplicaPool.InstanceGroupManagers.Get( + config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + if err != nil { + return err + } + + // check that total instance count is "size" + log.Printf("[DEBUG] XXXXXXXXXXXXXXXXXXXXXXXX Manager Test: %#v", manager.TargetSize) + if manager.CurrentSize != size { + return fmt.Errorf("instance count incorrect") + } + + // check that at least one instance exists in "targetpool" + tp, ok := s.RootModule().Resources[targetPool] + if !ok { + return fmt.Errorf("Not found: %s", targetPool) + } + + if tp.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + log.Printf("[DEBUG] XXXXXXXXXXXXXXXXXXXXXXXX Manager Test: %#v", tp) + + targetpool, err := config.clientCompute.TargetPools.Get( + config.Project, config.Region, tp.Primary.ID).Do() + if err != nil { + return err + } + + // check that total instance count is "size" + log.Printf("[DEBUG] XXXXXXXXXXXXXXXXXXXXXXXX Manager Test: %#v", len(targetpool.Instances)) + if len(targetpool.Instances) == 0 { + return fmt.Errorf("no instance in new targetpool") + } + + // check that the instance template updated + instanceTemplate, err := config.clientCompute.InstanceTemplates.Get( + config.Project, template).Do() + if err != nil { + return fmt.Errorf("Error reading instance template: %s", err) + } + + if instanceTemplate.Name != template { + return fmt.Errorf("instance template not updated") + } + + return nil + } +} + +const testAccInstanceGroupManager_basic = ` +resource "google_compute_instance_template" "foobar" { + name = "terraform-test-foobar" + machine_type = "n1-standard-1" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = "projects/debian-cloud/global/images/debian-7-wheezy-v20140814" + auto_delete = true + boot = true + } + + network { + source = "default" + } + + metadata { + foo = "bar" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_target_pool" "foobar" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-foobar" + session_affinity = "CLIENT_IP_PROTO" +} + +resource "google_replicapool_instance_group_manager" "foobar" { + description = "Terraform test instance group manager" + name = "terraform-test" + instance_template = "${google_compute_instance_template.foobar.self_link}" + target_pools = ["${google_compute_target_pool.foobar.self_link}"] + base_instance_name = "foobar" + zone = "us-central1-a" + size = 2 +}` + +const testAccInstanceGroupManager_update = ` +resource "google_compute_instance_template" "foobar" { + name = "terraform-test-foobar" + machine_type = "n1-standard-1" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = "projects/debian-cloud/global/images/debian-7-wheezy-v20140814" + auto_delete = true + boot = true + } + + network { + source = "default" + } + + metadata { + foo = "bar" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_instance_template" "foobaz" { + name = "terraform-test-foobaz" + machine_type = "n1-standard-1" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = "projects/debian-cloud/global/images/debian-7-wheezy-v20140814" + auto_delete = true + boot = true + } + + network { + source = "default" + } + + metadata { + foo = "bar" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_target_pool" "foobar" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-foobar" + session_affinity = "CLIENT_IP_PROTO" +} + +resource "google_compute_target_pool" "foobaz" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-foobaz" + session_affinity = "CLIENT_IP_PROTO" +} + +resource "google_replicapool_instance_group_manager" "foobar" { + description = "Terraform test instance group manager" + name = "terraform-test" + instance_template = "${google_compute_instance_template.foobar.self_link}" + target_pools = ["${google_compute_target_pool.foobaz.self_link}"] + base_instance_name = "foobar" + zone = "us-central1-a" + size = 2 +}` + +const testAccInstanceGroupManager_update2 = ` +resource "google_compute_instance_template" "foobar" { + name = "terraform-test-foobar" + machine_type = "n1-standard-1" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = "projects/debian-cloud/global/images/debian-7-wheezy-v20140814" + auto_delete = true + boot = true + } + + network { + source = "default" + } + + metadata { + foo = "bar" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_instance_template" "foobaz" { + name = "terraform-test-foobaz" + machine_type = "n1-standard-1" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = "projects/debian-cloud/global/images/debian-7-wheezy-v20140814" + auto_delete = true + boot = true + } + + network { + source = "default" + } + + metadata { + foo = "bar" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_target_pool" "foobar" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-foobar" + session_affinity = "CLIENT_IP_PROTO" +} + +resource "google_compute_target_pool" "foobaz" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-foobaz" + session_affinity = "CLIENT_IP_PROTO" +} + +resource "google_replicapool_instance_group_manager" "foobar" { + description = "Terraform test instance group manager" + name = "terraform-test" + instance_template = "${google_compute_instance_template.foobaz.self_link}" + target_pools = ["${google_compute_target_pool.foobaz.self_link}"] + base_instance_name = "foobar" + zone = "us-central1-a" + size = 3 +}` From 81d082830257846db84f48e7fd0c555a7ddb890b Mon Sep 17 00:00:00 2001 From: David Watson Date: Mon, 16 Feb 2015 16:07:26 +0000 Subject: [PATCH 02/73] Add tests for InstanceGroupManagers in GCE. --- ...apool_instance_group_manager.html.markdown | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 website/source/docs/providers/google/r/replicapool_instance_group_manager.html.markdown diff --git a/website/source/docs/providers/google/r/replicapool_instance_group_manager.html.markdown b/website/source/docs/providers/google/r/replicapool_instance_group_manager.html.markdown new file mode 100644 index 000000000..671ddb29d --- /dev/null +++ b/website/source/docs/providers/google/r/replicapool_instance_group_manager.html.markdown @@ -0,0 +1,65 @@ +--- +layout: "google" +page_title: "Google: google_replicapool_instance_group_manager" +sidebar_current: "docs-google-resource-instance_group_manager" +description: |- + Managers an Instance Group within GCE. +--- + +# google\_replicapool\_instance\_group\_manager + +The Google Compute Engine Instance Group Manager API creates and manages pools +of homogeneous Compute Engine virtual machine instances from a common instance +template. For more information, see [the official documentation](https://cloud.google.com/compute/docs/instance-groups/manager +and [API](https://cloud.google.com/compute/docs/instance-groups/manager/v1beta2/instanceGroupManagers) + +## Example Usage + +``` +resource "google_replicapool_instance_group_manager" "foobar" { + description = "Terraform test instance group manager" + name = "terraform-test" + instance_template = "${google_compute_instance_template.foobar.self_link}" + target_pools = ["${google_compute_target_pool.foobar.self_link}"] + base_instance_name = "foobar" + zone = "us-central1-a" + size = 2 +} +``` + +## Argument Refernce + +The following arguments are supported: + +* `base_instance_name` - (Required) The base instance name to use for +instances in this group. The value must be a valid [RFC1035](https://www.ietf.org/rfc/rfc1035.txt) name. +Supported characters are lowercase letters, numbers, and hyphens (-). Instances +are named by appending a hyphen and a random four-character string to the base +instance name. + +* `description` - (Optional) An optional textual description of the instance +group manager. + +* `instance_template` - (Required) The full URL to an instance template from +which all new instances will be created. + +* `name` - (Required) The name of the instance group manager. Must be 1-63 +characters long and comply with [RFC1035](https://www.ietf.org/rfc/rfc1035.txt). +Supported characters include lowercase letters, numbers, and hyphens. + +* `size` - (Required) The desired number of instance to be maintained in this +instance group manager. + +* `target_pools` - (Required) The full URL of all target pools to which new +instances in the group are added. Updating the target pool values does not +affect existing instances. + +* `zone` - (Required) The zone that instances in this group should be created in. + +## Attributes Reference + +The following attributes are exported: + +* `group` - The full URL of the instance group created by the manager. + +* `self_link` - The URL of the created resource. From fa6d945e08c6f4db94f72cb9813ce27c88e299cf Mon Sep 17 00:00:00 2001 From: David Watson Date: Thu, 19 Feb 2015 11:47:53 +0000 Subject: [PATCH 03/73] Update tests to include updated network definition for instance templates from #980. --- ...replicapool_instance_group_manager_test.go | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/builtin/providers/google/resource_replicapool_instance_group_manager_test.go b/builtin/providers/google/resource_replicapool_instance_group_manager_test.go index 3ddf0af37..4fd2a3b56 100644 --- a/builtin/providers/google/resource_replicapool_instance_group_manager_test.go +++ b/builtin/providers/google/resource_replicapool_instance_group_manager_test.go @@ -189,8 +189,8 @@ resource "google_compute_instance_template" "foobar" { boot = true } - network { - source = "default" + network_interface { + network = "default" } metadata { @@ -231,8 +231,8 @@ resource "google_compute_instance_template" "foobar" { boot = true } - network { - source = "default" + network_interface { + network = "default" } metadata { @@ -256,8 +256,8 @@ resource "google_compute_instance_template" "foobaz" { boot = true } - network { - source = "default" + network_interface { + network = "default" } metadata { @@ -304,8 +304,8 @@ resource "google_compute_instance_template" "foobar" { boot = true } - network { - source = "default" + network_interface { + network = "default" } metadata { @@ -329,8 +329,8 @@ resource "google_compute_instance_template" "foobaz" { boot = true } - network { - source = "default" + network_interface { + network = "default" } metadata { From de9d05244588abfa52056ec0ebd19ccb4b332788 Mon Sep 17 00:00:00 2001 From: David Watson Date: Thu, 19 Feb 2015 16:31:11 +0000 Subject: [PATCH 04/73] Remove debugging log lines. --- .../resource_replicapool_instance_group_manager_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/builtin/providers/google/resource_replicapool_instance_group_manager_test.go b/builtin/providers/google/resource_replicapool_instance_group_manager_test.go index 4fd2a3b56..16b79b9b3 100644 --- a/builtin/providers/google/resource_replicapool_instance_group_manager_test.go +++ b/builtin/providers/google/resource_replicapool_instance_group_manager_test.go @@ -2,7 +2,6 @@ package google import ( "fmt" - "log" "testing" "code.google.com/p/google-api-go-client/replicapool/v1beta2" @@ -122,7 +121,6 @@ func testAccCheckInstanceGroupManagerUpdated(n string, size int64, targetPool st if rs.Primary.ID == "" { return fmt.Errorf("No ID is set") } - log.Printf("[DEBUG] XXXXXXXXXXXXXXXXXXXXXXXX Manager Test: %#v", rs) config := testAccProvider.Meta().(*Config) @@ -133,7 +131,6 @@ func testAccCheckInstanceGroupManagerUpdated(n string, size int64, targetPool st } // check that total instance count is "size" - log.Printf("[DEBUG] XXXXXXXXXXXXXXXXXXXXXXXX Manager Test: %#v", manager.TargetSize) if manager.CurrentSize != size { return fmt.Errorf("instance count incorrect") } @@ -147,7 +144,6 @@ func testAccCheckInstanceGroupManagerUpdated(n string, size int64, targetPool st if tp.Primary.ID == "" { return fmt.Errorf("No ID is set") } - log.Printf("[DEBUG] XXXXXXXXXXXXXXXXXXXXXXXX Manager Test: %#v", tp) targetpool, err := config.clientCompute.TargetPools.Get( config.Project, config.Region, tp.Primary.ID).Do() @@ -156,7 +152,6 @@ func testAccCheckInstanceGroupManagerUpdated(n string, size int64, targetPool st } // check that total instance count is "size" - log.Printf("[DEBUG] XXXXXXXXXXXXXXXXXXXXXXXX Manager Test: %#v", len(targetpool.Instances)) if len(targetpool.Instances) == 0 { return fmt.Errorf("no instance in new targetpool") } From c706081dd4197a69f557298058c3c60e2ffe3b03 Mon Sep 17 00:00:00 2001 From: David Watson Date: Wed, 4 Mar 2015 10:14:59 +0000 Subject: [PATCH 05/73] Initial commit of autoscaler resource. --- builtin/providers/google/config.go | 7 + builtin/providers/google/operation.go | 47 +++ builtin/providers/google/provider.go | 1 + .../providers/google/resource_autoscaler.go | 366 ++++++++++++++++++ 4 files changed, 421 insertions(+) create mode 100644 builtin/providers/google/resource_autoscaler.go diff --git a/builtin/providers/google/config.go b/builtin/providers/google/config.go index 65c5b26bc..31d5ff468 100644 --- a/builtin/providers/google/config.go +++ b/builtin/providers/google/config.go @@ -7,6 +7,7 @@ import ( "net/http" "os" + "code.google.com/p/google-api-go-client/autoscaler/v1beta2" "code.google.com/p/google-api-go-client/compute/v1" "code.google.com/p/google-api-go-client/replicapool/v1beta2" @@ -24,6 +25,7 @@ type Config struct { clientCompute *compute.Service clientReplicaPool *replicapool.Service + clientAutoscaler *autoscaler.Service } func (c *Config) loadAndValidate() error { @@ -95,6 +97,11 @@ func (c *Config) loadAndValidate() error { return err } + c.clientAutoscaler, err = autoscaler.New(client) + if err != nil { + return err + } + return nil } diff --git a/builtin/providers/google/operation.go b/builtin/providers/google/operation.go index 141a7684c..286804c9c 100644 --- a/builtin/providers/google/operation.go +++ b/builtin/providers/google/operation.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" + "code.google.com/p/google-api-go-client/autoscaler/v1beta2" "code.google.com/p/google-api-go-client/compute/v1" "code.google.com/p/google-api-go-client/replicapool/v1beta2" "github.com/hashicorp/terraform/helper/resource" @@ -125,3 +126,49 @@ func (e ReplicaPoolOperationError) Error() string { return buf.String() } + +// Autoscaler Operations +type AutoscalerOperationWaiter struct { + Service *autoscaler.Service + Op *autoscaler.Operation + Project string + Zone string +} + +func (w *AutoscalerOperationWaiter) RefreshFunc() resource.StateRefreshFunc { + return func() (interface{}, string, error) { + var op *autoscaler.Operation + var err error + + op, err = w.Service.ZoneOperations.Get( + w.Project, w.Zone, w.Op.Name).Do() + + if err != nil { + return nil, "", err + } + + return op, op.Status, nil + } +} + +func (w *AutoscalerOperationWaiter) Conf() *resource.StateChangeConf { + return &resource.StateChangeConf{ + Pending: []string{"PENDING", "RUNNING"}, + Target: "DONE", + Refresh: w.RefreshFunc(), + } +} + +// AutoscalerOperationError wraps autoscaler.OperationError and implements the +// error interface so it can be returned. +type AutoscalerOperationError autoscaler.OperationError + +func (e AutoscalerOperationError) Error() string { + var buf bytes.Buffer + + for _, err := range e.Errors { + buf.WriteString(err.Message + "\n") + } + + return buf.String() +} diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index cf4093aa7..be39f4e8f 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -29,6 +29,7 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ + "google_autoscaler": resourceAutoscaler(), "google_compute_address": resourceComputeAddress(), "google_compute_disk": resourceComputeDisk(), "google_compute_firewall": resourceComputeFirewall(), diff --git a/builtin/providers/google/resource_autoscaler.go b/builtin/providers/google/resource_autoscaler.go new file mode 100644 index 000000000..ee9222577 --- /dev/null +++ b/builtin/providers/google/resource_autoscaler.go @@ -0,0 +1,366 @@ +package google + +import ( + "fmt" + "log" + "time" + + "code.google.com/p/google-api-go-client/autoscaler/v1beta2" + "code.google.com/p/google-api-go-client/googleapi" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAutoscaler() *schema.Resource { + return &schema.Resource{ + Create: resourceAutoscalerCreate, + Read: resourceAutoscalerRead, + Update: resourceAutoscalerUpdate, + Delete: resourceAutoscalerDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + + "target": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + + "autoscaling_policy": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "min_replicas": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + + "max_replicas": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + + "cooldown_period": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + + "cpu_utilization": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "target": &schema.Schema{ + Type: schema.TypeFloat, + Required: true, + }, + }, + }, + }, + + "metric": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "target": &schema.Schema{ + Type: schema.TypeFloat, + Required: true, + }, + + "type": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + + "load_balancing_utilization": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "target": &schema.Schema{ + Type: schema.TypeFloat, + Required: true, + }, + }, + }, + }, + }, + }, + }, + + "zone": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "self_link": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceAutoscalerCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + // Get the zone + log.Printf("[DEBUG] Loading zone: %s", d.Get("zone").(string)) + zone, err := config.clientCompute.Zones.Get( + config.Project, d.Get("zone").(string)).Do() + if err != nil { + return fmt.Errorf( + "Error loading zone '%s': %s", d.Get("zone").(string), err) + } + + // Build the parameter + scaler := &autoscaler.Autoscaler{ + Name: d.Get("name").(string), + Target: d.Get("target").(string), + } + + // Optional fields + if v, ok := d.GetOk("description"); ok { + scaler.Description = v.(string) + } + + prefix := "autoscaling_policy.0." + + scaler.AutoscalingPolicy = &autoscaler.AutoscalingPolicy{ + MaxNumReplicas: int64(d.Get(prefix + "max_replicas").(int)), + MinNumReplicas: int64(d.Get(prefix + "min_replicas").(int)), + CoolDownPeriodSec: int64(d.Get(prefix + "cooldown_period").(int)), + } + + // Check that only one autoscaling policy is defined + + policyCounter := 0 + if _, ok := d.GetOk(prefix + "cpu_utilization"); ok { + policyCounter++ + scaler.AutoscalingPolicy.CpuUtilization = &autoscaler.AutoscalingPolicyCpuUtilization{ + UtilizationTarget: d.Get(prefix + "cpu_utilization.0.target").(float64), + } + } + if _, ok := d.GetOk("autoscaling_policy.0.metric"); ok { + policyCounter++ + scaler.AutoscalingPolicy.CustomMetricUtilizations = []*autoscaler.AutoscalingPolicyCustomMetricUtilization{ + { + Metric: d.Get(prefix + "metric.0.name").(string), + UtilizationTarget: d.Get(prefix + "metric.0.target").(float64), + UtilizationTargetType: d.Get(prefix + "metric.0.type").(string), + }, + } + + } + if _, ok := d.GetOk("autoscaling_policy.0.load_balancing_utilization"); ok { + policyCounter++ + scaler.AutoscalingPolicy.LoadBalancingUtilization = &autoscaler.AutoscalingPolicyLoadBalancingUtilization{ + UtilizationTarget: d.Get(prefix + "load_balancing_utilization.0.target").(float64), + } + } + + if policyCounter != 1 { + return fmt.Errorf("One policy must be defined for an autoscaler.") + } + + op, err := config.clientAutoscaler.Autoscalers.Insert( + config.Project, zone.Name, scaler).Do() + if err != nil { + return fmt.Errorf("Error creating Autoscaler: %s", err) + } + + // It probably maybe worked, so store the ID now + d.SetId(scaler.Name) + + // Wait for the operation to complete + w := &AutoscalerOperationWaiter{ + Service: config.clientAutoscaler, + Op: op, + Project: config.Project, + Zone: zone.Name, + } + state := w.Conf() + state.Timeout = 2 * time.Minute + state.MinTimeout = 1 * time.Second + opRaw, err := state.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for Autoscaler to create: %s", err) + } + op = opRaw.(*autoscaler.Operation) + if op.Error != nil { + // The resource didn't actually create + d.SetId("") + + // Return the error + return AutoscalerOperationError(*op.Error) + } + + return resourceAutoscalerRead(d, meta) +} + +func resourceAutoscalerRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + zone := d.Get("zone").(string) + scaler, err := config.clientAutoscaler.Autoscalers.Get( + config.Project, zone, d.Id()).Do() + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + // The resource doesn't exist anymore + d.SetId("") + + return nil + } + + return fmt.Errorf("Error reading Autoscaler: %s", err) + } + + d.Set("self_link", scaler.SelfLink) + + return nil +} + +func resourceAutoscalerUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + zone := d.Get("zone").(string) + + // Build the parameter + scaler := &autoscaler.Autoscaler{ + Name: d.Get("name").(string), + Target: d.Get("target").(string), + } + + // Optional fields + if v, ok := d.GetOk("description"); ok { + scaler.Description = v.(string) + } + + prefix := "autoscaling_policy.0." + + scaler.AutoscalingPolicy = &autoscaler.AutoscalingPolicy{ + MaxNumReplicas: int64(d.Get(prefix + "max_replicas").(int)), + MinNumReplicas: int64(d.Get(prefix + "min_replicas").(int)), + CoolDownPeriodSec: int64(d.Get(prefix + "cooldown_period").(int)), + } + + // Check that only one autoscaling policy is defined + + policyCounter := 0 + if _, ok := d.GetOk(prefix + "cpu_utilization"); ok { + if d.Get(prefix+"cpu_utilization.0.target").(float64) != 0 { + policyCounter++ + scaler.AutoscalingPolicy.CpuUtilization = &autoscaler.AutoscalingPolicyCpuUtilization{ + UtilizationTarget: d.Get(prefix + "cpu_utilization.0.target").(float64), + } + } + } + if _, ok := d.GetOk("autoscaling_policy.0.metric"); ok { + if d.Get(prefix+"metric.0.name") != "" { + policyCounter++ + scaler.AutoscalingPolicy.CustomMetricUtilizations = []*autoscaler.AutoscalingPolicyCustomMetricUtilization{ + { + Metric: d.Get(prefix + "metric.0.name").(string), + UtilizationTarget: d.Get(prefix + "metric.0.target").(float64), + UtilizationTargetType: d.Get(prefix + "metric.0.type").(string), + }, + } + } + + } + if _, ok := d.GetOk("autoscaling_policy.0.load_balancing_utilization"); ok { + if d.Get(prefix+"load_balancing_utilization.0.target").(float64) != 0 { + policyCounter++ + scaler.AutoscalingPolicy.LoadBalancingUtilization = &autoscaler.AutoscalingPolicyLoadBalancingUtilization{ + UtilizationTarget: d.Get(prefix + "load_balancing_utilization.0.target").(float64), + } + } + } + + if policyCounter != 1 { + return fmt.Errorf("One policy must be defined for an autoscaler.") + } + + op, err := config.clientAutoscaler.Autoscalers.Patch( + config.Project, zone, d.Id(), scaler).Do() + if err != nil { + return fmt.Errorf("Error updating Autoscaler: %s", err) + } + + // It probably maybe worked, so store the ID now + d.SetId(scaler.Name) + + // Wait for the operation to complete + w := &AutoscalerOperationWaiter{ + Service: config.clientAutoscaler, + Op: op, + Project: config.Project, + Zone: zone, + } + state := w.Conf() + state.Timeout = 2 * time.Minute + state.MinTimeout = 1 * time.Second + opRaw, err := state.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for Autoscaler to update: %s", err) + } + op = opRaw.(*autoscaler.Operation) + if op.Error != nil { + // Return the error + return AutoscalerOperationError(*op.Error) + } + + return resourceAutoscalerRead(d, meta) +} + +func resourceAutoscalerDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + zone := d.Get("zone").(string) + op, err := config.clientAutoscaler.Autoscalers.Delete( + config.Project, zone, d.Id()).Do() + if err != nil { + return fmt.Errorf("Error deleting autoscaler: %s", err) + } + + // Wait for the operation to complete + w := &AutoscalerOperationWaiter{ + Service: config.clientAutoscaler, + Op: op, + Project: config.Project, + Zone: zone, + } + state := w.Conf() + state.Timeout = 2 * time.Minute + state.MinTimeout = 1 * time.Second + opRaw, err := state.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for Autoscaler to delete: %s", err) + } + op = opRaw.(*autoscaler.Operation) + if op.Error != nil { + // Return the error + return AutoscalerOperationError(*op.Error) + } + + d.SetId("") + return nil +} From 84bf1220dbf8b00d5cb3e5726d041064518d7d34 Mon Sep 17 00:00:00 2001 From: David Watson Date: Wed, 4 Mar 2015 10:15:26 +0000 Subject: [PATCH 06/73] Tests for GCE autoscaler resource. --- .../google/resource_autoscaler_test.go | 247 ++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 builtin/providers/google/resource_autoscaler_test.go diff --git a/builtin/providers/google/resource_autoscaler_test.go b/builtin/providers/google/resource_autoscaler_test.go new file mode 100644 index 000000000..6b2897e45 --- /dev/null +++ b/builtin/providers/google/resource_autoscaler_test.go @@ -0,0 +1,247 @@ +package google + +import ( + "fmt" + "testing" + + "code.google.com/p/google-api-go-client/autoscaler/v1beta2" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAutoscaler_basic(t *testing.T) { + var ascaler autoscaler.Autoscaler + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAutoscalerDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAutoscaler_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckAutoscalerExists( + "google_autoscaler.foobar", &ascaler), + ), + }, + }, + }) +} + +func TestAccAutoscaler_update(t *testing.T) { + var ascaler autoscaler.Autoscaler + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAutoscalerDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAutoscaler_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckAutoscalerExists( + "google_autoscaler.foobar", &ascaler), + ), + }, + resource.TestStep{ + Config: testAccAutoscaler_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckAutoscalerExists( + "google_autoscaler.foobar", &ascaler), + testAccCheckAutoscalerUpdated( + "google_autoscaler.foobar", 10), + ), + }, + }, + }) +} + +func testAccCheckAutoscalerDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "google_autoscaler" { + continue + } + + _, err := config.clientAutoscaler.Autoscalers.Get( + config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + if err == nil { + return fmt.Errorf("Autoscaler still exists") + } + } + + return nil +} + +func testAccCheckAutoscalerExists(n string, ascaler *autoscaler.Autoscaler) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + + found, err := config.clientAutoscaler.Autoscalers.Get( + config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + if err != nil { + return err + } + + if found.Name != rs.Primary.ID { + return fmt.Errorf("Autoscaler not found") + } + + *ascaler = *found + + return nil + } +} + +func testAccCheckAutoscalerUpdated(n string, max int64) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + + ascaler, err := config.clientAutoscaler.Autoscalers.Get( + config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() + if err != nil { + return err + } + + if ascaler.AutoscalingPolicy.MaxNumReplicas != max { + return fmt.Errorf("maximum replicas incorrect") + } + + return nil + } +} + +const testAccAutoscaler_basic = ` +resource "google_compute_instance_template" "foobar" { + name = "terraform-test-template-foobar" + machine_type = "n1-standard-1" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = "projects/debian-cloud/global/images/debian-7-wheezy-v20140814" + auto_delete = true + boot = true + } + + network_interface { + network = "default" + } + + metadata { + foo = "bar" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_target_pool" "foobar" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-tpool-foobar" + session_affinity = "CLIENT_IP_PROTO" +} + +resource "google_replicapool_instance_group_manager" "foobar" { + description = "Terraform test instance group manager" + name = "terraform-test-groupmanager" + instance_template = "${google_compute_instance_template.foobar.self_link}" + target_pools = ["${google_compute_target_pool.foobar.self_link}"] + base_instance_name = "foobar" + zone = "us-central1-a" + size = 0 +} + +resource "google_autoscaler" "foobar" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-ascaler" + zone = "us-central1-a" + target = "${google_replicapool_instance_group_manager.foobar.self_link}" + autoscaling_policy = { + max_replicas = 5 + min_replicas = 0 + cooldown_period = 60 + cpu_utilization = { + target = 0.5 + } + } + +}` + +const testAccAutoscaler_update = ` +resource "google_compute_instance_template" "foobar" { + name = "terraform-test-template-foobar" + machine_type = "n1-standard-1" + can_ip_forward = false + tags = ["foo", "bar"] + + disk { + source_image = "projects/debian-cloud/global/images/debian-7-wheezy-v20140814" + auto_delete = true + boot = true + } + + network_interface { + network = "default" + } + + metadata { + foo = "bar" + } + + service_account { + scopes = ["userinfo-email", "compute-ro", "storage-ro"] + } +} + +resource "google_compute_target_pool" "foobar" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-tpool-foobar" + session_affinity = "CLIENT_IP_PROTO" +} + +resource "google_replicapool_instance_group_manager" "foobar" { + description = "Terraform test instance group manager" + name = "terraform-test-groupmanager" + instance_template = "${google_compute_instance_template.foobar.self_link}" + target_pools = ["${google_compute_target_pool.foobar.self_link}"] + base_instance_name = "foobar" + zone = "us-central1-a" + size = 0 +} + +resource "google_autoscaler" "foobar" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-ascaler" + zone = "us-central1-a" + target = "${google_replicapool_instance_group_manager.foobar.self_link}" + autoscaling_policy = { + max_replicas = 10 + min_replicas = 0 + cooldown_period = 60 + cpu_utilization = { + target = 0.5 + } + } + +}` From 70b7243dd6606286ec77f7b4448ca5d4f572e0c5 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Tue, 30 Jun 2015 12:54:32 +0100 Subject: [PATCH 07/73] helper: Add resource.PrefixedUniqueId --- helper/resource/id.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/helper/resource/id.go b/helper/resource/id.go index b3af422fc..ea0ae1916 100644 --- a/helper/resource/id.go +++ b/helper/resource/id.go @@ -9,13 +9,18 @@ import ( const UniqueIdPrefix = `terraform-` -// Helper for a resource to generate a unique identifier +// Helper for a resource to generate a unique identifier w/ default prefix +func UniqueId() string { + return PrefixedUniqueId(UniqueIdPrefix) +} + +// Helper for a resource to generate a unique identifier w/ given prefix // // This uses a simple RFC 4122 v4 UUID with some basic cosmetic filters // applied (base32, remove padding, downcase) to make visually distinguishing // identifiers easier. -func UniqueId() string { - return fmt.Sprintf("%s%s", UniqueIdPrefix, +func PrefixedUniqueId(prefix string) string { + return fmt.Sprintf("%s%s", prefix, strings.ToLower( strings.Replace( base32.StdEncoding.EncodeToString(uuidV4()), From 676d490d403f4234b5a2baa579328da28c49d476 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Tue, 30 Jun 2015 13:01:07 +0100 Subject: [PATCH 08/73] provider/aws: Allow elb name to be generated --- builtin/providers/aws/resource_aws_elb.go | 16 +++++++++++++--- .../docs/providers/aws/r/elb.html.markdown | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/builtin/providers/aws/resource_aws_elb.go b/builtin/providers/aws/resource_aws_elb.go index b76cc7131..8a5c9b413 100644 --- a/builtin/providers/aws/resource_aws_elb.go +++ b/builtin/providers/aws/resource_aws_elb.go @@ -11,6 +11,7 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/elb" "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" ) @@ -24,7 +25,8 @@ func resourceAwsElb() *schema.Resource { Schema: map[string]*schema.Schema{ "name": &schema.Schema{ Type: schema.TypeString, - Required: true, + Optional: true, + Computed: true, ForceNew: true, ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { value := v.(string) @@ -211,10 +213,18 @@ func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error { return err } + var elbName string + if v, ok := d.GetOk("name"); ok { + elbName = v.(string) + } else { + elbName = resource.PrefixedUniqueId("tf-lb-") + d.Set("name", elbName) + } + tags := tagsFromMapELB(d.Get("tags").(map[string]interface{})) // Provision the elb elbOpts := &elb.CreateLoadBalancerInput{ - LoadBalancerName: aws.String(d.Get("name").(string)), + LoadBalancerName: aws.String(elbName), Listeners: listeners, Tags: tags, } @@ -241,7 +251,7 @@ func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error { } // Assign the elb's unique identifier for use later - d.SetId(d.Get("name").(string)) + d.SetId(elbName) log.Printf("[INFO] ELB ID: %s", d.Id()) // Enable partial mode and record what we set diff --git a/website/source/docs/providers/aws/r/elb.html.markdown b/website/source/docs/providers/aws/r/elb.html.markdown index 9c63788d3..824a5507f 100644 --- a/website/source/docs/providers/aws/r/elb.html.markdown +++ b/website/source/docs/providers/aws/r/elb.html.markdown @@ -57,7 +57,7 @@ resource "aws_elb" "bar" { The following arguments are supported: -* `name` - (Required) The name of the ELB +* `name` - (Optional) The name of the ELB. By default generated by terraform. * `availability_zones` - (Required for an EC2-classic ELB) The AZ's to serve traffic in. * `security_groups` - (Optional) A list of security group IDs to assign to the ELB. * `subnets` - (Required for a VPC ELB) A list of subnet IDs to attach to the ELB. From 975e1a6c2c7af386060da504b82d14e19b1deeab Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Tue, 14 Jul 2015 16:39:50 -0500 Subject: [PATCH 09/73] provider/aws: Check credentials before attempting to do anything --- builtin/providers/aws/config.go | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index bc465394c..a1a0dd361 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform/helper/multierror" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/aws/aws-sdk-go/service/cloudwatch" @@ -85,6 +86,14 @@ func (c *Config) Client() (interface{}, error) { MaxRetries: c.MaxRetries, } + log.Println("[INFO] Initializing IAM Connection") + client.iamconn = iam.New(awsConfig) + + err := c.ValidateCredentials(client.iamconn) + if err != nil { + errs = append(errs, err) + } + log.Println("[INFO] Initializing DynamoDB connection") client.dynamodbconn = dynamodb.New(awsConfig) @@ -103,15 +112,12 @@ func (c *Config) Client() (interface{}, error) { log.Println("[INFO] Initializing RDS Connection") client.rdsconn = rds.New(awsConfig) - log.Println("[INFO] Initializing IAM Connection") - client.iamconn = iam.New(awsConfig) - log.Println("[INFO] Initializing Kinesis Connection") client.kinesisconn = kinesis.New(awsConfig) - err := c.ValidateAccountId(client.iamconn) - if err != nil { - errs = append(errs, err) + authErr := c.ValidateAccountId(client.iamconn) + if authErr != nil { + errs = append(errs, authErr) } log.Println("[INFO] Initializing AutoScaling connection") @@ -165,6 +171,21 @@ func (c *Config) ValidateRegion() error { return fmt.Errorf("Not a valid region: %s", c.Region) } +// Validate credentials early and fail before we do any graph walking +func (c *Config) ValidateCredentials(iamconn *iam.IAM) error { + _, err := iamconn.GetUser(nil) + if err != nil { + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "SignatureDoesNotMatch" { + return fmt.Errorf("Failed authenticating with AWS: please verify credentials") + } + } + return err + } + + return nil +} + // ValidateAccountId returns a context-specific error if the configured account // id is explicitly forbidden or not authorised; and nil if it is authorised. func (c *Config) ValidateAccountId(iamconn *iam.IAM) error { From 94ef573b662df831dce0469bdbea50bf0146bdc8 Mon Sep 17 00:00:00 2001 From: David Radcliffe Date: Fri, 17 Jul 2015 17:04:22 -0400 Subject: [PATCH 10/73] DNSimple does not support changing a record domain or type --- builtin/providers/dnsimple/resource_dnsimple_record.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builtin/providers/dnsimple/resource_dnsimple_record.go b/builtin/providers/dnsimple/resource_dnsimple_record.go index 644876cd8..82002ab83 100644 --- a/builtin/providers/dnsimple/resource_dnsimple_record.go +++ b/builtin/providers/dnsimple/resource_dnsimple_record.go @@ -19,6 +19,7 @@ func resourceDNSimpleRecord() *schema.Resource { "domain": &schema.Schema{ Type: schema.TypeString, Required: true, + ForceNew: true, }, "domain_id": &schema.Schema{ @@ -39,6 +40,7 @@ func resourceDNSimpleRecord() *schema.Resource { "type": &schema.Schema{ Type: schema.TypeString, Required: true, + ForceNew: true, }, "value": &schema.Schema{ From f1cc9fafb3550e304f0982a6424c6b905c186179 Mon Sep 17 00:00:00 2001 From: David Radcliffe Date: Fri, 17 Jul 2015 17:07:01 -0400 Subject: [PATCH 11/73] =?UTF-8?q?=E2=80=9CDNS=20Simple=E2=80=9D=20should?= =?UTF-8?q?=20be=20=E2=80=9CDNSimple=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../providers/dnsimple/resource_dnsimple_record.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/builtin/providers/dnsimple/resource_dnsimple_record.go b/builtin/providers/dnsimple/resource_dnsimple_record.go index 82002ab83..a16a41f35 100644 --- a/builtin/providers/dnsimple/resource_dnsimple_record.go +++ b/builtin/providers/dnsimple/resource_dnsimple_record.go @@ -76,12 +76,12 @@ func resourceDNSimpleRecordCreate(d *schema.ResourceData, meta interface{}) erro newRecord.Ttl = ttl.(string) } - log.Printf("[DEBUG] DNS Simple Record create configuration: %#v", newRecord) + log.Printf("[DEBUG] DNSimple Record create configuration: %#v", newRecord) recId, err := client.CreateRecord(d.Get("domain").(string), newRecord) if err != nil { - return fmt.Errorf("Failed to create DNS Simple Record: %s", err) + return fmt.Errorf("Failed to create DNSimple Record: %s", err) } d.SetId(recId) @@ -95,7 +95,7 @@ func resourceDNSimpleRecordRead(d *schema.ResourceData, meta interface{}) error rec, err := client.RetrieveRecord(d.Get("domain").(string), d.Id()) if err != nil { - return fmt.Errorf("Couldn't find DNS Simple Record: %s", err) + return fmt.Errorf("Couldn't find DNSimple Record: %s", err) } d.Set("domain_id", rec.StringDomainId()) @@ -135,11 +135,11 @@ func resourceDNSimpleRecordUpdate(d *schema.ResourceData, meta interface{}) erro updateRecord.Ttl = attr.(string) } - log.Printf("[DEBUG] DNS Simple Record update configuration: %#v", updateRecord) + log.Printf("[DEBUG] DNSimple Record update configuration: %#v", updateRecord) _, err := client.UpdateRecord(d.Get("domain").(string), d.Id(), updateRecord) if err != nil { - return fmt.Errorf("Failed to update DNS Simple Record: %s", err) + return fmt.Errorf("Failed to update DNSimple Record: %s", err) } return resourceDNSimpleRecordRead(d, meta) @@ -148,12 +148,12 @@ func resourceDNSimpleRecordUpdate(d *schema.ResourceData, meta interface{}) erro func resourceDNSimpleRecordDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*dnsimple.Client) - log.Printf("[INFO] Deleting DNS Simple Record: %s, %s", d.Get("domain").(string), d.Id()) + log.Printf("[INFO] Deleting DNSimple Record: %s, %s", d.Get("domain").(string), d.Id()) err := client.DestroyRecord(d.Get("domain").(string), d.Id()) if err != nil { - return fmt.Errorf("Error deleting DNS Simple Record: %s", err) + return fmt.Errorf("Error deleting DNSimple Record: %s", err) } return nil From db5d0301d8d411a611785723d5efae5d626ca869 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Mon, 20 Jul 2015 12:32:58 -0500 Subject: [PATCH 12/73] provider/aws: Fix issue with toggling monitoring in AWS Instances --- builtin/providers/aws/resource_aws_instance.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go index 9a4306acb..6d6657c15 100644 --- a/builtin/providers/aws/resource_aws_instance.go +++ b/builtin/providers/aws/resource_aws_instance.go @@ -579,6 +579,24 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { } } + if d.HasChange("monitoring") { + var mErr error + if d.Get("monitoring").(bool) { + log.Printf("[DEBUG] Enabling monitoring for Instance (%s)", d.Id()) + _, mErr = conn.MonitorInstances(&ec2.MonitorInstancesInput{ + InstanceIDs: []*string{aws.String(d.Id())}, + }) + } else { + log.Printf("[DEBUG] Disabling monitoring for Instance (%s)", d.Id()) + _, mErr = conn.UnmonitorInstances(&ec2.UnmonitorInstancesInput{ + InstanceIDs: []*string{aws.String(d.Id())}, + }) + } + if mErr != nil { + return fmt.Errorf("[WARN] Error updating Instance monitoring: %s", mErr) + } + } + // TODO(mitchellh): wait for the attributes we modified to // persist the change... From 4c67368dd85604674e1d7df0198a929d560b87e6 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Mon, 20 Jul 2015 20:03:29 +0000 Subject: [PATCH 13/73] v0.6.1 --- CHANGELOG.md | 2 +- deps/v0-6-1.json | 385 +++++++++++++++++++++++++++++++++++++++++++ terraform/version.go | 2 +- 3 files changed, 387 insertions(+), 2 deletions(-) create mode 100644 deps/v0-6-1.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 52739f739..ad3ad3065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.6.1 (Unreleased) +## 0.6.1 (July 20, 2015) FEATURES: diff --git a/deps/v0-6-1.json b/deps/v0-6-1.json new file mode 100644 index 000000000..69bbd10dc --- /dev/null +++ b/deps/v0-6-1.json @@ -0,0 +1,385 @@ +{ + "ImportPath": "github.com/hashicorp/terraform", + "GoVersion": "go1.4.2", + "Packages": [ + "./..." + ], + "Deps": [ + { + "ImportPath": "code.google.com/p/go-uuid/uuid", + "Comment": "null-15", + "Rev": "35bc42037350f0078e3c974c6ea690f1926603ab" + }, + { + "ImportPath": "github.com/Azure/azure-sdk-for-go/core/http", + "Comment": "v1.2-216-g9197765", + "Rev": "91977650587a7bc48318c0430649d7fea886f111" + }, + { + "ImportPath": "github.com/Azure/azure-sdk-for-go/core/tls", + "Comment": "v1.2-216-g9197765", + "Rev": "91977650587a7bc48318c0430649d7fea886f111" + }, + { + "ImportPath": "github.com/Azure/azure-sdk-for-go/management", + "Comment": "v1.2-216-g9197765", + "Rev": "91977650587a7bc48318c0430649d7fea886f111" + }, + { + "ImportPath": "github.com/Azure/azure-sdk-for-go/storage", + "Comment": "v1.2-216-g9197765", + "Rev": "91977650587a7bc48318c0430649d7fea886f111" + }, + { + "ImportPath": "github.com/Azure/go-pkcs12", + "Rev": "a635c0684cd517745ca5c9552a312627791d5ba0" + }, + { + "ImportPath": "github.com/armon/circbuf", + "Rev": "f092b4f207b6e5cce0569056fba9e1a2735cb6cf" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/aws", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/endpoints", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/ec2query", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/json/jsonutil", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/jsonrpc", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/query", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/rest", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/restjson", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/restxml", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/internal/signer/v4", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/cloudwatch", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/dynamodb", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/ec2", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/ecs", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/elasticache", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/elb", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/iam", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/kinesis", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/lambda", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/rds", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/route53", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/s3", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/sns", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/aws/aws-sdk-go/service/sqs", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/awslabs/aws-sdk-go/aws/credentials", + "Comment": "v0.6.7-3-g2a6648c", + "Rev": "2a6648c479175ce005bca95780f948a196a46062" + }, + { + "ImportPath": "github.com/cyberdelia/heroku-go/v3", + "Rev": "594d483b9b6a8ddc7cd2f1e3e7d1de92fa2de665" + }, + { + "ImportPath": "github.com/dylanmei/iso8601", + "Rev": "2075bf119b58e5576c6ed9f867b8f3d17f2e54d4" + }, + { + "ImportPath": "github.com/dylanmei/winrmtest", + "Rev": "3e9661c52c45dab9a8528966a23d421922fca9b9" + }, + { + "ImportPath": "github.com/fsouza/go-dockerclient", + "Rev": "f6e9f5396e0e8f34472efe443d0cb7f9af162b88" + }, + { + "ImportPath": "github.com/hashicorp/atlas-go/archive", + "Comment": "20141209094003-71-g785958f", + "Rev": "785958ffcd6a8857890651f3f4d9a289ddc27633" + }, + { + "ImportPath": "github.com/hashicorp/atlas-go/v1", + "Comment": "20141209094003-71-g785958f", + "Rev": "785958ffcd6a8857890651f3f4d9a289ddc27633" + }, + { + "ImportPath": "github.com/hashicorp/consul/api", + "Comment": "v0.5.2-159-gc34bcb4", + "Rev": "c34bcb45c670af076846826ea72c436fbd0e2c35" + }, + { + "ImportPath": "github.com/hashicorp/errwrap", + "Rev": "7554cd9344cec97297fa6649b055a8c98c2a1e55" + }, + { + "ImportPath": "github.com/hashicorp/go-checkpoint", + "Rev": "88326f6851319068e7b34981032128c0b1a6524d" + }, + { + "ImportPath": "github.com/hashicorp/go-multierror", + "Rev": "56912fb08d85084aa318edcf2bba735b97cf35c5" + }, + { + "ImportPath": "github.com/hashicorp/go-version", + "Rev": "999359b6b7a041ce16e695d51e92145b83f01087" + }, + { + "ImportPath": "github.com/hashicorp/hcl", + "Rev": "54864211433d45cb780682431585b3e573b49e4a" + }, + { + "ImportPath": "github.com/hashicorp/yamux", + "Rev": "8e00b30457b1486b012f204b82ec92ae6b547de8" + }, + { + "ImportPath": "github.com/imdario/mergo", + "Comment": "0.2.0-5-g61a5285", + "Rev": "61a52852277811e93e06d28e0d0c396284a7730b" + }, + { + "ImportPath": "github.com/masterzen/simplexml/dom", + "Rev": "95ba30457eb1121fa27753627c774c7cd4e90083" + }, + { + "ImportPath": "github.com/masterzen/winrm/soap", + "Rev": "23128e7b3dc1f8091aeff7aae82cb2112ce53c75" + }, + { + "ImportPath": "github.com/masterzen/winrm/winrm", + "Rev": "23128e7b3dc1f8091aeff7aae82cb2112ce53c75" + }, + { + "ImportPath": "github.com/masterzen/xmlpath", + "Rev": "13f4951698adc0fa9c1dda3e275d489a24201161" + }, + { + "ImportPath": "github.com/mitchellh/cli", + "Rev": "8102d0ed5ea2709ade1243798785888175f6e415" + }, + { + "ImportPath": "github.com/mitchellh/colorstring", + "Rev": "61164e49940b423ba1f12ddbdf01632ac793e5e9" + }, + { + "ImportPath": "github.com/mitchellh/copystructure", + "Rev": "6fc66267e9da7d155a9d3bd489e00dad02666dc6" + }, + { + "ImportPath": "github.com/mitchellh/go-homedir", + "Rev": "1f6da4a72e57d4e7edd4a7295a585e0a3999a2d4" + }, + { + "ImportPath": "github.com/mitchellh/go-linereader", + "Rev": "07bab5fdd9580500aea6ada0e09df4aa28e68abd" + }, + { + "ImportPath": "github.com/mitchellh/mapstructure", + "Rev": "281073eb9eb092240d33ef253c404f1cca550309" + }, + { + "ImportPath": "github.com/mitchellh/osext", + "Rev": "0dd3f918b21bec95ace9dc86c7e70266cfc5c702" + }, + { + "ImportPath": "github.com/mitchellh/packer/common/uuid", + "Comment": "v0.8.2-4-g2010a0c", + "Rev": "2010a0c966175b3c0fa8d158a879c10acbba0d76" + }, + { + "ImportPath": "github.com/mitchellh/panicwrap", + "Rev": "45cbfd3bae250c7676c077fb275be1a2968e066a" + }, + { + "ImportPath": "github.com/mitchellh/prefixedio", + "Rev": "89d9b535996bf0a185f85b59578f2e245f9e1724" + }, + { + "ImportPath": "github.com/mitchellh/reflectwalk", + "Rev": "eecf4c70c626c7cfbb95c90195bc34d386c74ac6" + }, + { + "ImportPath": "github.com/nu7hatch/gouuid", + "Rev": "179d4d0c4d8d407a32af483c2354df1d2c91e6c3" + }, + { + "ImportPath": "github.com/packer-community/winrmcp/winrmcp", + "Rev": "743b1afe5ee3f6d5ba71a0d50673fa0ba2123d6b" + }, + { + "ImportPath": "github.com/pearkes/cloudflare", + "Rev": "19e280b056f3742e535ea12ae92a37ea7767ea82" + }, + { + "ImportPath": "github.com/pearkes/digitalocean", + "Rev": "e966f00c2d9de5743e87697ab77c7278f5998914" + }, + { + "ImportPath": "github.com/pearkes/dnsimple", + "Rev": "2a807d118c9e52e94819f414a6ec0293b45cad01" + }, + { + "ImportPath": "github.com/pearkes/mailgun", + "Rev": "5b02e7e9ffee9869f81393e80db138f6ff726260" + }, + { + "ImportPath": "github.com/rackspace/gophercloud", + "Comment": "v1.0.0-623-ge83aa01", + "Rev": "e83aa011e019917c7bd951444d61c42431b4d21d" + }, + { + "ImportPath": "github.com/satori/go.uuid", + "Rev": "afe1e2ddf0f05b7c29d388a3f8e76cb15c2231ca" + }, + { + "ImportPath": "github.com/soniah/dnsmadeeasy", + "Comment": "v1.1-2-g5578a8c", + "Rev": "5578a8c15e33958c61cf7db720b6181af65f4a9e" + }, + { + "ImportPath": "github.com/vaughan0/go-ini", + "Rev": "a98ad7ee00ec53921f08832bc06ecf7fd600e6a1" + }, + { + "ImportPath": "github.com/xanzy/go-cloudstack/cloudstack", + "Comment": "v1.2.0-36-g0031956", + "Rev": "00319560eeca5e6ffef3ba048c97c126a465854f" + }, + { + "ImportPath": "golang.org/x/crypto/ssh", + "Rev": "7d5b0be716b9d6d4269afdaae10032bb296d3cdf" + }, + { + "ImportPath": "golang.org/x/net/context", + "Rev": "f0cf018861e2b54077eced91659e255072b5f215" + }, + { + "ImportPath": "golang.org/x/oauth2", + "Rev": "8914e5017ca260f2a3a1575b1e6868874050d95e" + }, + { + "ImportPath": "google.golang.org/api/compute/v1", + "Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121" + }, + { + "ImportPath": "google.golang.org/api/container/v1", + "Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121" + }, + { + "ImportPath": "google.golang.org/api/dns/v1", + "Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121" + }, + { + "ImportPath": "google.golang.org/api/googleapi", + "Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121" + }, + { + "ImportPath": "google.golang.org/api/storage/v1", + "Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121" + }, + { + "ImportPath": "google.golang.org/cloud/compute/metadata", + "Rev": "522a8ceb4bb83c2def27baccf31d646bce11a4b2" + }, + { + "ImportPath": "google.golang.org/cloud/internal", + "Rev": "522a8ceb4bb83c2def27baccf31d646bce11a4b2" + } + ] +} diff --git a/terraform/version.go b/terraform/version.go index 9cbc9adb1..8c25f6642 100644 --- a/terraform/version.go +++ b/terraform/version.go @@ -6,4 +6,4 @@ const Version = "0.6.1" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "dev" +const VersionPrerelease = "" From 71103642985b754f0ad95d6599026ab0c503792e Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Mon, 20 Jul 2015 16:03:53 -0500 Subject: [PATCH 14/73] release: clean up after v0.6.1 --- CHANGELOG.md | 2 ++ terraform/version.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad3ad3065..343e9477b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.6.2 (Unreleased) + ## 0.6.1 (July 20, 2015) FEATURES: diff --git a/terraform/version.go b/terraform/version.go index 8c25f6642..78f3e5ff7 100644 --- a/terraform/version.go +++ b/terraform/version.go @@ -1,9 +1,9 @@ package terraform // The main version number that is being run at the moment. -const Version = "0.6.1" +const Version = "0.6.2" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release // such as "dev" (in development), "beta", "rc1", etc. -const VersionPrerelease = "" +const VersionPrerelease = "dev" From ed12f7cbb57883361931359820f0a78d6c06802e Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Mon, 20 Jul 2015 16:19:41 -0500 Subject: [PATCH 15/73] updates for RELEASING --- RELEASING.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RELEASING.md b/RELEASING.md index 2b8955543..41a6b8059 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -51,9 +51,13 @@ git tag -m "${VERSION}" "${VERSION}" # Build the release make release +# Add Godeps for the archive +git add Godeps + # Make an archive with vendored dependencies -stashName=$(git stash) +stashName=$(git stash create) git archive -o terraform-$VERSION-src.tar.gz $stashName +git reset --hard ${VERSION} # Zip and push release to bintray export BINTRAY_API_KEY="..." From dfbe7bee9e00e68f1ec62a583fd3ac6024d3e03b Mon Sep 17 00:00:00 2001 From: Clint Date: Tue, 21 Jul 2015 08:36:27 -0500 Subject: [PATCH 16/73] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 343e9477b..9480c2086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## 0.6.2 (Unreleased) +IMPROVEMENTS: + + * provider/aws: Validate credentials before walking the graph [GH-2730] + ## 0.6.1 (July 20, 2015) FEATURES: From 4797a82e1ad3424c4dfd394f3b9857fa8581aa80 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Tue, 21 Jul 2015 15:57:59 +0200 Subject: [PATCH 17/73] aws: Simplify ValidateCredentials func --- builtin/providers/aws/config.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index a1a0dd361..f58938285 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -174,16 +174,14 @@ func (c *Config) ValidateRegion() error { // Validate credentials early and fail before we do any graph walking func (c *Config) ValidateCredentials(iamconn *iam.IAM) error { _, err := iamconn.GetUser(nil) - if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - if awsErr.Code() == "SignatureDoesNotMatch" { - return fmt.Errorf("Failed authenticating with AWS: please verify credentials") - } + + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "SignatureDoesNotMatch" { + return fmt.Errorf("Failed authenticating with AWS: please verify credentials") } - return err } - return nil + return err } // ValidateAccountId returns a context-specific error if the configured account From 3688d4ba0086f919a528ef166a4a4bb3262341a6 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Tue, 21 Jul 2015 09:42:02 -0500 Subject: [PATCH 18/73] provider/aws: Converge on TestAccAWS for acceptance tests names An attempt to converge the tests into a standard naming scheme - TestAccAWS for aws tests - a `_basic` test for each suite, save a few that are quick (Network ACLs, for example) --- .../aws/resource_aws_customer_gateway_test.go | 2 +- .../providers/aws/resource_aws_flow_log_test.go | 4 ++-- .../resource_aws_iam_server_certificate_test.go | 2 +- .../aws/resource_aws_kinesis_stream_test.go | 2 +- .../aws/resource_aws_lambda_function_test.go | 2 +- .../resource_aws_route53_delegation_set_test.go | 4 ++-- .../resource_aws_route53_health_check_test.go | 4 ++-- .../aws/resource_aws_route53_record_test.go | 16 ++++++++-------- ...resource_aws_route53_zone_association_test.go | 4 ++-- .../aws/resource_aws_route53_zone_test.go | 6 +++--- .../aws/resource_aws_vpc_dhcp_options_test.go | 2 +- .../aws/resource_aws_vpc_endpoint_test.go | 4 ++-- builtin/providers/aws/resource_aws_vpc_test.go | 10 +++++----- .../aws/resource_aws_vpn_gateway_test.go | 2 +- 14 files changed, 32 insertions(+), 32 deletions(-) diff --git a/builtin/providers/aws/resource_aws_customer_gateway_test.go b/builtin/providers/aws/resource_aws_customer_gateway_test.go index 33e370946..9e3daec6d 100644 --- a/builtin/providers/aws/resource_aws_customer_gateway_test.go +++ b/builtin/providers/aws/resource_aws_customer_gateway_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccCustomerGateway_basic(t *testing.T) { +func TestAccAWSCustomerGateway_basic(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, diff --git a/builtin/providers/aws/resource_aws_flow_log_test.go b/builtin/providers/aws/resource_aws_flow_log_test.go index b938a6fea..a7dd9ad32 100644 --- a/builtin/providers/aws/resource_aws_flow_log_test.go +++ b/builtin/providers/aws/resource_aws_flow_log_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccFlowLog_basic(t *testing.T) { +func TestAccAWSFlowLog_basic(t *testing.T) { var flowLog ec2.FlowLog lgn := os.Getenv("LOG_GROUP_NAME") @@ -31,7 +31,7 @@ func TestAccFlowLog_basic(t *testing.T) { }) } -func TestAccFlowLog_subnet(t *testing.T) { +func TestAccAWSFlowLog_subnet(t *testing.T) { var flowLog ec2.FlowLog lgn := os.Getenv("LOG_GROUP_NAME") diff --git a/builtin/providers/aws/resource_aws_iam_server_certificate_test.go b/builtin/providers/aws/resource_aws_iam_server_certificate_test.go index 3165416fc..5982a8b6c 100644 --- a/builtin/providers/aws/resource_aws_iam_server_certificate_test.go +++ b/builtin/providers/aws/resource_aws_iam_server_certificate_test.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccIAMServerCertificate_basic(t *testing.T) { +func TestAccAWSIAMServerCertificate_basic(t *testing.T) { var cert iam.ServerCertificate resource.Test(t, resource.TestCase{ diff --git a/builtin/providers/aws/resource_aws_kinesis_stream_test.go b/builtin/providers/aws/resource_aws_kinesis_stream_test.go index 01d14d3d0..814ea92d2 100644 --- a/builtin/providers/aws/resource_aws_kinesis_stream_test.go +++ b/builtin/providers/aws/resource_aws_kinesis_stream_test.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccKinesisStream_basic(t *testing.T) { +func TestAccAWSKinesisStream_basic(t *testing.T) { var stream kinesis.StreamDescription resource.Test(t, resource.TestCase{ diff --git a/builtin/providers/aws/resource_aws_lambda_function_test.go b/builtin/providers/aws/resource_aws_lambda_function_test.go index d85bd7e8d..12edb99e0 100644 --- a/builtin/providers/aws/resource_aws_lambda_function_test.go +++ b/builtin/providers/aws/resource_aws_lambda_function_test.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccAWSLambdaFunction_normal(t *testing.T) { +func TestAccAWSLambdaFunction_basic(t *testing.T) { var conf lambda.GetFunctionOutput resource.Test(t, resource.TestCase{ diff --git a/builtin/providers/aws/resource_aws_route53_delegation_set_test.go b/builtin/providers/aws/resource_aws_route53_delegation_set_test.go index 8de0e1b83..f9bf3cd87 100644 --- a/builtin/providers/aws/resource_aws_route53_delegation_set_test.go +++ b/builtin/providers/aws/resource_aws_route53_delegation_set_test.go @@ -13,7 +13,7 @@ import ( "github.com/aws/aws-sdk-go/service/route53" ) -func TestAccRoute53DelegationSet_basic(t *testing.T) { +func TestAccAWSRoute53DelegationSet_basic(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -29,7 +29,7 @@ func TestAccRoute53DelegationSet_basic(t *testing.T) { }) } -func TestAccRoute53DelegationSet_withZones(t *testing.T) { +func TestAccAWSRoute53DelegationSet_withZones(t *testing.T) { var zone route53.GetHostedZoneOutput resource.Test(t, resource.TestCase{ diff --git a/builtin/providers/aws/resource_aws_route53_health_check_test.go b/builtin/providers/aws/resource_aws_route53_health_check_test.go index 32286cc41..e27de56d4 100644 --- a/builtin/providers/aws/resource_aws_route53_health_check_test.go +++ b/builtin/providers/aws/resource_aws_route53_health_check_test.go @@ -10,7 +10,7 @@ import ( "github.com/aws/aws-sdk-go/service/route53" ) -func TestAccRoute53HealthCheck_basic(t *testing.T) { +func TestAccAWSRoute53HealthCheck_basic(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -34,7 +34,7 @@ func TestAccRoute53HealthCheck_basic(t *testing.T) { }) } -func TestAccRoute53HealthCheck_IpConfig(t *testing.T) { +func TestAccAWSRoute53HealthCheck_IpConfig(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, diff --git a/builtin/providers/aws/resource_aws_route53_record_test.go b/builtin/providers/aws/resource_aws_route53_record_test.go index eaa6abb7a..08f824ccb 100644 --- a/builtin/providers/aws/resource_aws_route53_record_test.go +++ b/builtin/providers/aws/resource_aws_route53_record_test.go @@ -50,7 +50,7 @@ func TestExpandRecordName(t *testing.T) { } } -func TestAccRoute53Record_basic(t *testing.T) { +func TestAccAWSRoute53Record_basic(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -66,7 +66,7 @@ func TestAccRoute53Record_basic(t *testing.T) { }) } -func TestAccRoute53Record_txtSupport(t *testing.T) { +func TestAccAWSRoute53Record_txtSupport(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -82,7 +82,7 @@ func TestAccRoute53Record_txtSupport(t *testing.T) { }) } -func TestAccRoute53Record_generatesSuffix(t *testing.T) { +func TestAccAWSRoute53Record_generatesSuffix(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -98,7 +98,7 @@ func TestAccRoute53Record_generatesSuffix(t *testing.T) { }) } -func TestAccRoute53Record_wildcard(t *testing.T) { +func TestAccAWSRoute53Record_wildcard(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -122,7 +122,7 @@ func TestAccRoute53Record_wildcard(t *testing.T) { }) } -func TestAccRoute53Record_weighted(t *testing.T) { +func TestAccAWSRoute53Record_weighted(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -139,7 +139,7 @@ func TestAccRoute53Record_weighted(t *testing.T) { }) } -func TestAccRoute53Record_alias(t *testing.T) { +func TestAccAWSRoute53Record_alias(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -155,7 +155,7 @@ func TestAccRoute53Record_alias(t *testing.T) { }) } -func TestAccRoute53Record_weighted_alias(t *testing.T) { +func TestAccAWSRoute53Record_weighted_alias(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -182,7 +182,7 @@ func TestAccRoute53Record_weighted_alias(t *testing.T) { }) } -func TestAccRoute53Record_TypeChange(t *testing.T) { +func TestAccAWSRoute53Record_TypeChange(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, diff --git a/builtin/providers/aws/resource_aws_route53_zone_association_test.go b/builtin/providers/aws/resource_aws_route53_zone_association_test.go index e929d4d31..b04b3bb51 100644 --- a/builtin/providers/aws/resource_aws_route53_zone_association_test.go +++ b/builtin/providers/aws/resource_aws_route53_zone_association_test.go @@ -12,7 +12,7 @@ import ( "github.com/aws/aws-sdk-go/service/route53" ) -func TestAccRoute53ZoneAssociation_basic(t *testing.T) { +func TestAccAWSRoute53ZoneAssociation_basic(t *testing.T) { var zone route53.HostedZone resource.Test(t, resource.TestCase{ @@ -30,7 +30,7 @@ func TestAccRoute53ZoneAssociation_basic(t *testing.T) { }) } -func TestAccRoute53ZoneAssociation_region(t *testing.T) { +func TestAccAWSRoute53ZoneAssociation_region(t *testing.T) { var zone route53.HostedZone // record the initialized providers so that we can use them to diff --git a/builtin/providers/aws/resource_aws_route53_zone_test.go b/builtin/providers/aws/resource_aws_route53_zone_test.go index 92ab8a217..4fa1d51a8 100644 --- a/builtin/providers/aws/resource_aws_route53_zone_test.go +++ b/builtin/providers/aws/resource_aws_route53_zone_test.go @@ -64,7 +64,7 @@ func TestCleanChangeID(t *testing.T) { } } -func TestAccRoute53Zone_basic(t *testing.T) { +func TestAccAWSRoute53Zone_basic(t *testing.T) { var zone route53.GetHostedZoneOutput var td route53.ResourceTagSet @@ -85,7 +85,7 @@ func TestAccRoute53Zone_basic(t *testing.T) { }) } -func TestAccRoute53Zone_private_basic(t *testing.T) { +func TestAccAWSRoute53Zone_private_basic(t *testing.T) { var zone route53.GetHostedZoneOutput resource.Test(t, resource.TestCase{ @@ -104,7 +104,7 @@ func TestAccRoute53Zone_private_basic(t *testing.T) { }) } -func TestAccRoute53Zone_private_region(t *testing.T) { +func TestAccAWSRoute53Zone_private_region(t *testing.T) { var zone route53.GetHostedZoneOutput // record the initialized providers so that we can use them to diff --git a/builtin/providers/aws/resource_aws_vpc_dhcp_options_test.go b/builtin/providers/aws/resource_aws_vpc_dhcp_options_test.go index 988c8b3c4..e47f4d89d 100644 --- a/builtin/providers/aws/resource_aws_vpc_dhcp_options_test.go +++ b/builtin/providers/aws/resource_aws_vpc_dhcp_options_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccDHCPOptions_basic(t *testing.T) { +func TestAccAWSDHCPOptions_basic(t *testing.T) { var d ec2.DHCPOptions resource.Test(t, resource.TestCase{ diff --git a/builtin/providers/aws/resource_aws_vpc_endpoint_test.go b/builtin/providers/aws/resource_aws_vpc_endpoint_test.go index 6a29b688e..3d3055494 100644 --- a/builtin/providers/aws/resource_aws_vpc_endpoint_test.go +++ b/builtin/providers/aws/resource_aws_vpc_endpoint_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccVpcEndpoint_basic(t *testing.T) { +func TestAccAWSVpcEndpoint_basic(t *testing.T) { var endpoint ec2.VPCEndpoint resource.Test(t, resource.TestCase{ @@ -29,7 +29,7 @@ func TestAccVpcEndpoint_basic(t *testing.T) { }) } -func TestAccVpcEndpoint_withRouteTableAndPolicy(t *testing.T) { +func TestAccAWSVpcEndpoint_withRouteTableAndPolicy(t *testing.T) { var endpoint ec2.VPCEndpoint var routeTable ec2.RouteTable diff --git a/builtin/providers/aws/resource_aws_vpc_test.go b/builtin/providers/aws/resource_aws_vpc_test.go index 95121ec6f..a55fc2af7 100644 --- a/builtin/providers/aws/resource_aws_vpc_test.go +++ b/builtin/providers/aws/resource_aws_vpc_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform/terraform" ) -func TestAccVpc_basic(t *testing.T) { +func TestAccAWSVpc_basic(t *testing.T) { var vpc ec2.VPC resource.Test(t, resource.TestCase{ @@ -32,7 +32,7 @@ func TestAccVpc_basic(t *testing.T) { }) } -func TestAccVpc_dedicatedTenancy(t *testing.T) { +func TestAccAWSVpc_dedicatedTenancy(t *testing.T) { var vpc ec2.VPC resource.Test(t, resource.TestCase{ @@ -52,7 +52,7 @@ func TestAccVpc_dedicatedTenancy(t *testing.T) { }) } -func TestAccVpc_tags(t *testing.T) { +func TestAccAWSVpc_tags(t *testing.T) { var vpc ec2.VPC resource.Test(t, resource.TestCase{ @@ -83,7 +83,7 @@ func TestAccVpc_tags(t *testing.T) { }) } -func TestAccVpcUpdate(t *testing.T) { +func TestAccAWSVpc_update(t *testing.T) { var vpc ec2.VPC resource.Test(t, resource.TestCase{ @@ -187,7 +187,7 @@ func testAccCheckVpcExists(n string, vpc *ec2.VPC) resource.TestCheckFunc { } // https://github.com/hashicorp/terraform/issues/1301 -func TestAccVpc_bothDnsOptionsSet(t *testing.T) { +func TestAccAWSVpc_bothDnsOptionsSet(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, diff --git a/builtin/providers/aws/resource_aws_vpn_gateway_test.go b/builtin/providers/aws/resource_aws_vpn_gateway_test.go index 6b1d3fc48..c39970c93 100644 --- a/builtin/providers/aws/resource_aws_vpn_gateway_test.go +++ b/builtin/providers/aws/resource_aws_vpn_gateway_test.go @@ -87,7 +87,7 @@ func TestAccAWSVpnGateway_delete(t *testing.T) { }) } -func TestAccVpnGateway_tags(t *testing.T) { +func TestAccAWSVpnGateway_tags(t *testing.T) { var v ec2.VPNGateway resource.Test(t, resource.TestCase{ From ce204a89bba37af6bfe5fb812092526d018d1fd7 Mon Sep 17 00:00:00 2001 From: Clint Date: Tue, 21 Jul 2015 10:23:28 -0500 Subject: [PATCH 19/73] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9480c2086..08fe190d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ IMPROVEMENTS: * provider/aws: Validate credentials before walking the graph [GH-2730] +BUG FIXES: + + * provider/aws: Fix issue with toggling monitoring in AWS Instances [GH-2794] + ## 0.6.1 (July 20, 2015) FEATURES: From 87239dcec89fd3b518513cbedf77ed5eb19bac04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Naveiras?= Date: Tue, 21 Jul 2015 17:18:50 +0200 Subject: [PATCH 20/73] Amend AWS spot instace state name cancelled --- builtin/providers/aws/resource_aws_spot_instance_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_spot_instance_request.go b/builtin/providers/aws/resource_aws_spot_instance_request.go index 464a3de0c..bed4c42cb 100644 --- a/builtin/providers/aws/resource_aws_spot_instance_request.go +++ b/builtin/providers/aws/resource_aws_spot_instance_request.go @@ -160,7 +160,7 @@ func resourceAwsSpotInstanceRequestRead(d *schema.ResourceData, meta interface{} request := resp.SpotInstanceRequests[0] // if the request is cancelled, then it is gone - if *request.State == "canceled" { + if *request.State == "cancelled" { d.SetId("") return nil } From 90c3e06628268cd1a133679f30d12310d550dc0b Mon Sep 17 00:00:00 2001 From: Clint Date: Tue, 21 Jul 2015 10:44:19 -0500 Subject: [PATCH 21/73] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08fe190d3..9aeb0bc69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ IMPROVEMENTS: BUG FIXES: * provider/aws: Fix issue with toggling monitoring in AWS Instances [GH-2794] + * provider/aws: Fix issue with Spot Instance Requests and cancellation [GH-2805] ## 0.6.1 (July 20, 2015) From b720387449969ddf2a8ad64d93060fa1cce2d45f Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Tue, 21 Jul 2015 11:13:41 -0500 Subject: [PATCH 22/73] provider/aws: Clean up externally removed Launch Configurations Handle Launch Configurations that are not found more gracefully, but tolerating an additional API error indicating the LC no longer exists. --- builtin/providers/aws/resource_aws_launch_configuration.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_launch_configuration.go b/builtin/providers/aws/resource_aws_launch_configuration.go index ab6350b38..85630aa5a 100644 --- a/builtin/providers/aws/resource_aws_launch_configuration.go +++ b/builtin/providers/aws/resource_aws_launch_configuration.go @@ -480,7 +480,8 @@ func resourceAwsLaunchConfigurationDelete(d *schema.ResourceData, meta interface }) if err != nil { autoscalingerr, ok := err.(awserr.Error) - if ok && autoscalingerr.Code() == "InvalidConfiguration.NotFound" { + if ok && (autoscalingerr.Code() == "InvalidConfiguration.NotFound" || autoscalingerr.Code() == "ValidationError") { + log.Printf("[DEBUG] Launch configuration (%s) not found", d.Id()) return nil } From 9cb3150535b81f82d702e029ed395917c8ec8a11 Mon Sep 17 00:00:00 2001 From: Clint Date: Tue, 21 Jul 2015 15:53:33 -0500 Subject: [PATCH 23/73] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aeb0bc69..4a3386d3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ IMPROVEMENTS: * provider/aws: Validate credentials before walking the graph [GH-2730] + * provider/aws: ELB names are now optional, and generated by Terraform if omitted [GH-2571] BUG FIXES: From 7a60174dd170c43e35aa2fb1dd0201512bc72d16 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 22 Jul 2015 12:49:05 +0200 Subject: [PATCH 24/73] Do not print errors via UiHook --- command/hook_ui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/command/hook_ui.go b/command/hook_ui.go index c9543b3f6..6a10ceefb 100644 --- a/command/hook_ui.go +++ b/command/hook_ui.go @@ -140,7 +140,8 @@ func (h *UiHook) PostApply( } if applyerr != nil { - msg = fmt.Sprintf("Error: %s", applyerr) + // Errors are collected and printed in ApplyCommand, no need to duplicate + return terraform.HookActionContinue, nil } h.ui.Output(h.Colorize.Color(fmt.Sprintf( From 8e477b78d83860c07f168f5dcec8670d938d4b8f Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 22 Jul 2015 12:50:06 +0200 Subject: [PATCH 25/73] Add resource ID to errors coming from apply --- terraform/eval_apply.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/terraform/eval_apply.go b/terraform/eval_apply.go index cebf68265..c22a6ca4e 100644 --- a/terraform/eval_apply.go +++ b/terraform/eval_apply.go @@ -94,7 +94,8 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { // if we have one, otherwise we just output it. if err != nil { if n.Error != nil { - *n.Error = multierror.Append(*n.Error, err) + helpfulErr := fmt.Errorf("%s: %s", n.Info.Id, err.Error()) + *n.Error = multierror.Append(*n.Error, helpfulErr) } else { return nil, err } From a22dc2a9a2c63fceaa23be564478243eb6f641ac Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 22 Jul 2015 13:51:14 +0200 Subject: [PATCH 26/73] Add resource ID to refresh errors --- terraform/eval_refresh.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/terraform/eval_refresh.go b/terraform/eval_refresh.go index 3d25ecc8b..fa2b8126c 100644 --- a/terraform/eval_refresh.go +++ b/terraform/eval_refresh.go @@ -1,6 +1,7 @@ package terraform import ( + "fmt" "log" ) @@ -35,7 +36,7 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) { // Refresh! state, err = provider.Refresh(n.Info, state) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %s", n.Info.Id, err.Error()) } // Call post-refresh hook From 57dfaa492296698641aa509cf06447aa2c868955 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 22 Jul 2015 14:26:40 +0200 Subject: [PATCH 27/73] provider/aws: Add acceptance test for ELB w/out name --- .../providers/aws/resource_aws_elb_test.go | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/builtin/providers/aws/resource_aws_elb_test.go b/builtin/providers/aws/resource_aws_elb_test.go index ea56bf1da..d0d4d8d94 100644 --- a/builtin/providers/aws/resource_aws_elb_test.go +++ b/builtin/providers/aws/resource_aws_elb_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "reflect" + "regexp" "sort" "testing" @@ -74,6 +75,27 @@ func TestAccAWSELB_fullCharacterRange(t *testing.T) { }) } +func TestAccAWSELB_generatedName(t *testing.T) { + var conf elb.LoadBalancerDescription + generatedNameRegexp := regexp.MustCompile("^tf-lb-") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSELBDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSELBGeneratedName, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSELBExists("aws_elb.foo", &conf), + resource.TestMatchResourceAttr( + "aws_elb.foo", "name", generatedNameRegexp), + ), + }, + }, + }) +} + func TestAccAWSELB_tags(t *testing.T) { var conf elb.LoadBalancerDescription var td elb.TagDescription @@ -592,6 +614,19 @@ resource "aws_elb" "foo" { } ` +const testAccAWSELBGeneratedName = ` +resource "aws_elb" "foo" { + availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] + + listener { + instance_port = 8000 + instance_protocol = "http" + lb_port = 80 + lb_protocol = "http" + } +} +` + const testAccAWSELBConfig_TagUpdate = ` resource "aws_elb" "bar" { name = "foobar-terraform-test" From cbe9be4571f89295397cb57b3bf452695cf2dd18 Mon Sep 17 00:00:00 2001 From: John Engelman Date: Wed, 3 Jun 2015 10:10:17 -0500 Subject: [PATCH 28/73] Add website_domain for S3 buckets. --- .../aws/resource_aws_route53_record_test.go | 42 +++++++++++++++++++ .../providers/aws/resource_aws_s3_bucket.go | 40 +++++++++++++----- .../aws/website_endpoint_url_test.go | 6 +-- .../providers/aws/r/s3_bucket.html.markdown | 1 + 4 files changed, 75 insertions(+), 14 deletions(-) diff --git a/builtin/providers/aws/resource_aws_route53_record_test.go b/builtin/providers/aws/resource_aws_route53_record_test.go index 08f824ccb..0435dffb1 100644 --- a/builtin/providers/aws/resource_aws_route53_record_test.go +++ b/builtin/providers/aws/resource_aws_route53_record_test.go @@ -155,6 +155,22 @@ func TestAccAWSRoute53Record_alias(t *testing.T) { }) } +func TestAccAWSRoute53Record_s3_alias(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53RecordDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccRoute53S3AliasRecord, + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53RecordExists("aws_route53_record.alias"), + ), + }, + }, + }) +} + func TestAccAWSRoute53Record_weighted_alias(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -449,6 +465,32 @@ resource "aws_route53_record" "alias" { } ` +const testAccRoute53S3AliasRecord = ` +resource "aws_route53_zone" "main" { + name = "notexample.com" +} + +resource "aws_s3_bucket" "website" { + bucket = "website.notexample.com" + acl = "public-read" + website { + index_document = "index.html" + } +} + +resource "aws_route53_record" "alias" { + zone_id = "${aws_route53_zone.main.zone_id}" + name = "www" + type = "A" + + alias { + zone_id = "${aws_s3_bucket.website.hosted_zone_id}" + name = "${aws_s3_bucket.website.website_domain}" + evaluate_target_health = true + } +} +` + const testAccRoute53WeightedElbAliasRecord = ` resource "aws_route53_zone" "main" { name = "notexample.com" diff --git a/builtin/providers/aws/resource_aws_s3_bucket.go b/builtin/providers/aws/resource_aws_s3_bucket.go index 93bf24390..af60e2214 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket.go +++ b/builtin/providers/aws/resource_aws_s3_bucket.go @@ -77,12 +77,16 @@ func resourceAwsS3Bucket() *schema.Resource { Optional: true, Computed: true, }, - "website_endpoint": &schema.Schema{ Type: schema.TypeString, Optional: true, Computed: true, }, + "website_domain": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, "tags": tagsSchema(), @@ -237,12 +241,17 @@ func resourceAwsS3BucketRead(d *schema.ResourceData, meta interface{}) error { } // Add website_endpoint as an attribute - endpoint, err := websiteEndpoint(s3conn, d) + websiteEndpoint, err := websiteEndpoint(s3conn, d) if err != nil { return err } - if err := d.Set("website_endpoint", endpoint); err != nil { - return err + if websiteEndpoint != nil { + if err := d.Set("website_endpoint", websiteEndpoint.Endpoint); err != nil { + return err + } + if err := d.Set("website_domain", websiteEndpoint.Domain); err != nil { + return err + } } tagSet, err := getTagSetS3(s3conn, d.Id()) @@ -405,11 +414,11 @@ func resourceAwsS3BucketWebsiteDelete(s3conn *s3.S3, d *schema.ResourceData) err return nil } -func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (string, error) { +func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (*S3Website, error) { // If the bucket doesn't have a website configuration, return an empty // endpoint if _, ok := d.GetOk("website"); !ok { - return "", nil + return nil, nil } bucket := d.Get("bucket").(string) @@ -421,26 +430,31 @@ func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (string, error) { }, ) if err != nil { - return "", err + return nil, err } var region string if location.LocationConstraint != nil { region = *location.LocationConstraint } - return WebsiteEndpointUrl(bucket, region), nil + return WebsiteEndpoint(bucket, region), nil } -func WebsiteEndpointUrl(bucket string, region string) string { +func WebsiteEndpoint(bucket string, region string) *S3Website { + domain := WebsiteDomainUrl(region) + return &S3Website{Endpoint: fmt.Sprintf("%s.%s", bucket, domain), Domain: domain} +} + +func WebsiteDomainUrl(region string) string { region = normalizeRegion(region) // Frankfurt(and probably future) regions uses different syntax for website endpoints // http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html if region == "eu-central-1" { - return fmt.Sprintf("%s.s3-website.%s.amazonaws.com", bucket, region) + return fmt.Sprintf("s3-website.%s.amazonaws.com", region) } - return fmt.Sprintf("%s.s3-website-%s.amazonaws.com", bucket, region) + return fmt.Sprintf("s3-website-%s.amazonaws.com", region) } func normalizeJson(jsonString interface{}) string { @@ -465,3 +479,7 @@ func normalizeRegion(region string) string { return region } + +type S3Website struct { + Endpoint, Domain string +} diff --git a/builtin/providers/aws/website_endpoint_url_test.go b/builtin/providers/aws/website_endpoint_url_test.go index 2f4ce5249..bbe282e2c 100644 --- a/builtin/providers/aws/website_endpoint_url_test.go +++ b/builtin/providers/aws/website_endpoint_url_test.go @@ -20,9 +20,9 @@ var websiteEndpoints = []struct { func TestWebsiteEndpointUrl(t *testing.T) { for _, tt := range websiteEndpoints { - s := WebsiteEndpointUrl("bucket-name", tt.in) - if s != tt.out { - t.Errorf("WebsiteEndpointUrl(\"bucket-name\", %q) => %q, want %q", tt.in, s, tt.out) + s := WebsiteEndpoint("bucket-name", tt.in) + if s.Endpoint != tt.out { + t.Errorf("WebsiteEndpointUrl(\"bucket-name\", %q) => %q, want %q", tt.in, s.Endpoint, tt.out) } } } diff --git a/website/source/docs/providers/aws/r/s3_bucket.html.markdown b/website/source/docs/providers/aws/r/s3_bucket.html.markdown index 4f367d4f8..f30c153c5 100644 --- a/website/source/docs/providers/aws/r/s3_bucket.html.markdown +++ b/website/source/docs/providers/aws/r/s3_bucket.html.markdown @@ -67,3 +67,4 @@ The following attributes are exported: * `hosted_zone_id` - The [Route 53 Hosted Zone ID](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_website_region_endpoints) for this bucket's region. * `region` - The AWS region this bucket resides in. * `website_endpoint` - The website endpoint, if the bucket is configured with a website. If not, this will be an empty string. +* `website_domain` - The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records. From 78eb236786a418ec78bfc413418cbec791606688 Mon Sep 17 00:00:00 2001 From: Clint Date: Wed, 22 Jul 2015 11:06:31 -0500 Subject: [PATCH 29/73] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a3386d3f..159240163 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ IMPROVEMENTS: * provider/aws: Validate credentials before walking the graph [GH-2730] + * provider/aws: Add website_domain for S3 buckets [GH-2210] * provider/aws: ELB names are now optional, and generated by Terraform if omitted [GH-2571] BUG FIXES: From 761c8ab225e180dff207fc0ba943496e63ce4a6d Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Wed, 22 Jul 2015 20:59:45 +0200 Subject: [PATCH 30/73] Fix link in the docs --- website/source/layouts/cloudstack.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/layouts/cloudstack.erb b/website/source/layouts/cloudstack.erb index 1cf60b787..84c52e2df 100644 --- a/website/source/layouts/cloudstack.erb +++ b/website/source/layouts/cloudstack.erb @@ -54,7 +54,7 @@ > - cloudstack_secondary_ipaddress + cloudstack_secondary_ipaddress > From 5554942721ec71c4a42d5c305d9c02a4361e3a0c Mon Sep 17 00:00:00 2001 From: Jesse Szwedko Date: Wed, 15 Jul 2015 18:42:32 +0000 Subject: [PATCH 31/73] This adds the source_dest_check attribute to the aws_network_interface resource Defaults to true to be consistent with AWS --- .../aws/resource_aws_network_interface.go | 19 +++++++++ .../resource_aws_network_interface_test.go | 42 +++++++++++++++++++ .../aws/r/network_interface.markdown | 2 + 3 files changed, 63 insertions(+) diff --git a/builtin/providers/aws/resource_aws_network_interface.go b/builtin/providers/aws/resource_aws_network_interface.go index aee50f0aa..2cf7b13c3 100644 --- a/builtin/providers/aws/resource_aws_network_interface.go +++ b/builtin/providers/aws/resource_aws_network_interface.go @@ -46,6 +46,12 @@ func resourceAwsNetworkInterface() *schema.Resource { Set: schema.HashString, }, + "source_dest_check": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "attachment": &schema.Schema{ Type: schema.TypeSet, Optional: true, @@ -127,6 +133,7 @@ func resourceAwsNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) e d.Set("subnet_id", eni.SubnetID) d.Set("private_ips", flattenNetworkInterfacesPrivateIPAddesses(eni.PrivateIPAddresses)) d.Set("security_groups", flattenGroupIdentifiers(eni.Groups)) + d.Set("source_dest_check", eni.SourceDestCheck) // Tags d.Set("tags", tagsToMap(eni.TagSet)) @@ -221,6 +228,18 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) d.SetPartial("attachment") } + request := &ec2.ModifyNetworkInterfaceAttributeInput{ + NetworkInterfaceID: aws.String(d.Id()), + SourceDestCheck: &ec2.AttributeBooleanValue{Value: aws.Boolean(d.Get("source_dest_check").(bool))}, + } + + _, err := conn.ModifyNetworkInterfaceAttribute(request) + if err != nil { + return fmt.Errorf("Failure updating ENI: %s", err) + } + + d.SetPartial("source_dest_check") + if d.HasChange("security_groups") { request := &ec2.ModifyNetworkInterfaceAttributeInput{ NetworkInterfaceID: aws.String(d.Id()), diff --git a/builtin/providers/aws/resource_aws_network_interface_test.go b/builtin/providers/aws/resource_aws_network_interface_test.go index f83698abf..a444a0136 100644 --- a/builtin/providers/aws/resource_aws_network_interface_test.go +++ b/builtin/providers/aws/resource_aws_network_interface_test.go @@ -57,6 +57,26 @@ func TestAccAWSENI_attached(t *testing.T) { }) } +func TestAccAWSENI_sourceDestCheck(t *testing.T) { + var conf ec2.NetworkInterface + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSENIDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSENIConfigWithSourceDestCheck, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSENIExists("aws_network_interface.bar", &conf), + resource.TestCheckResourceAttr( + "aws_network_interface.bar", "source_dest_check", "false"), + ), + }, + }, + }) +} + func testAccCheckAWSENIExists(n string, res *ec2.NetworkInterface) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -108,6 +128,10 @@ func testAccCheckAWSENIAttributes(conf *ec2.NetworkInterface) resource.TestCheck return fmt.Errorf("expected private ip to be 172.16.10.100, but was %s", *conf.PrivateIPAddress) } + if *conf.SourceDestCheck != true { + return fmt.Errorf("expected source_dest_check to be true, but was %t", *conf.SourceDestCheck) + } + if len(conf.TagSet) == 0 { return fmt.Errorf("expected tags") } @@ -201,6 +225,24 @@ resource "aws_network_interface" "bar" { } ` +const testAccAWSENIConfigWithSourceDestCheck = ` +resource "aws_vpc" "foo" { + cidr_block = "172.16.0.0/16" +} + +resource "aws_subnet" "foo" { + vpc_id = "${aws_vpc.foo.id}" + cidr_block = "172.16.10.0/24" + availability_zone = "us-west-2a" +} + +resource "aws_network_interface" "bar" { + subnet_id = "${aws_subnet.foo.id}" + source_dest_check = false + private_ips = ["172.16.10.100"] +} +` + const testAccAWSENIConfigWithAttachment = ` resource "aws_vpc" "foo" { cidr_block = "172.16.0.0/16" diff --git a/website/source/docs/providers/aws/r/network_interface.markdown b/website/source/docs/providers/aws/r/network_interface.markdown index 8144d8f0f..0384b184a 100644 --- a/website/source/docs/providers/aws/r/network_interface.markdown +++ b/website/source/docs/providers/aws/r/network_interface.markdown @@ -32,6 +32,7 @@ The following arguments are supported: * `private_ips` - (Optional) List of private IPs to assign to the ENI. * `security_groups` - (Optional) List of security group IDs to assign to the ENI. * `attachment` - (Required) Block to define the attachment of the ENI. Documented below. +* `source_dest_check` - (Optional) Whether to enable source destination checking for the ENI. Default true. * `tags` - (Optional) A mapping of tags to assign to the resource. The `attachment` block supports: @@ -47,5 +48,6 @@ The following attributes are exported: * `private_ips` - List of private IPs assigned to the ENI. * `security_groups` - List of security groups attached to the ENI. * `attachment` - Block defining the attachment of the ENI. +* `source_dest_check` - Whether source destination checking is enabled * `tags` - Tags assigned to the ENI. From 7092b8ba8a341f842d1fe9c441b27edad5affe55 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Thu, 23 Jul 2015 01:01:13 -0700 Subject: [PATCH 32/73] Split AWS provider topics by service. With so many AWS provider resources, the docs are getting pretty hard to navigate. This is particularly true due to the mismatch of some resources encoding the service name (like aws_route53_record) but some others ignoring it (like aws_subnet) or using a generic prefix (like aws_db_instance), which causes an alphabetical ordering to muddle up all of the services. Since the AWS UI and docs are themselves oriented around services, most users should be familiar with the service brands and understand which resources belong to which service. Thus this categorization follows the primary categorization used within the AWS Console, preferring EC2-VPC over EC2-Classic-style bucketing. --- website/source/layouts/aws.erb | 636 +++++++++++++++++++-------------- 1 file changed, 373 insertions(+), 263 deletions(-) diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index cf1034231..a212bb697 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -1,296 +1,406 @@ <% wrap_layout :inner do %> - <% content_for :sidebar do %> - + <% end %> + + <%= yield %> <% end %> From 8ce3d49895095bbb505d61ead7f79985a04172e3 Mon Sep 17 00:00:00 2001 From: Clint Date: Thu, 23 Jul 2015 11:27:17 -0500 Subject: [PATCH 33/73] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 159240163..8cec80916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,9 @@ IMPROVEMENTS: * provider/aws: Validate credentials before walking the graph [GH-2730] - * provider/aws: Add website_domain for S3 buckets [GH-2210] + * provider/aws: Added website_domain for S3 buckets [GH-2210] * provider/aws: ELB names are now optional, and generated by Terraform if omitted [GH-2571] + * provider/aws: Added `source_dest_check` attribute to the aws_network_interface [GH-2741] BUG FIXES: From 8ac28c12f3654613d342354ea0ab9e70530ac314 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Fri, 24 Jul 2015 10:01:41 -0500 Subject: [PATCH 34/73] provider/aws: Fix issue with checking for ElastiCache cluster status --- .../aws/resource_aws_elasticache_cluster.go | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/builtin/providers/aws/resource_aws_elasticache_cluster.go b/builtin/providers/aws/resource_aws_elasticache_cluster.go index fa0d6b746..e364c8d48 100644 --- a/builtin/providers/aws/resource_aws_elasticache_cluster.go +++ b/builtin/providers/aws/resource_aws_elasticache_cluster.go @@ -186,16 +186,18 @@ func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{ log.Printf("[DEBUG] Restoring Redis cluster from S3 snapshot: %#v", s) } - _, err := conn.CreateCacheCluster(req) + resp, err := conn.CreateCacheCluster(req) if err != nil { return fmt.Errorf("Error creating Elasticache: %s", err) } + d.SetId(*resp.CacheCluster.CacheClusterID) + pending := []string{"creating"} stateConf := &resource.StateChangeConf{ Pending: pending, Target: "available", - Refresh: cacheClusterStateRefreshFunc(conn, d.Id(), "available", pending), + Refresh: cacheClusterStateRefreshFunc(conn, *resp.CacheCluster.CacheClusterID, "available", pending), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, @@ -207,8 +209,6 @@ func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{ return fmt.Errorf("Error waiting for elasticache (%s) to be created: %s", d.Id(), sterr) } - d.SetId(clusterId) - return resourceAwsElasticacheClusterRead(d, meta) } @@ -418,11 +418,27 @@ func cacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, give return nil, "", err } - c := resp.CacheClusters[0] - log.Printf("[DEBUG] status: %v", *c.CacheClusterStatus) + if len(resp.CacheClusters) == 0 { + return nil, "", fmt.Errorf("[WARN] Error: no Cache Clusters found for id (%s)", clusterID) + } + + var c *elasticache.CacheCluster + for _, cluster := range resp.CacheClusters { + if *cluster.CacheClusterID == clusterID { + log.Printf("[DEBUG] Found matching ElastiCache cluster: %s", *cluster.CacheClusterID) + c = cluster + } + } + + if c == nil { + return nil, "", fmt.Errorf("[WARN] Error: no matching Elastic Cache cluster for id (%s)", clusterID) + } + + log.Printf("[DEBUG] ElastiCache Cluster (%s) status: %v", clusterID, *c.CacheClusterStatus) // return the current state if it's in the pending array for _, p := range pending { + log.Printf("[DEBUG] ElastiCache: checking pending state (%s) for cluster (%s), cluster status: %s", pending, clusterID, *c.CacheClusterStatus) s := *c.CacheClusterStatus if p == s { log.Printf("[DEBUG] Return with status: %v", *c.CacheClusterStatus) @@ -432,18 +448,24 @@ func cacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, give // return given state if it's not in pending if givenState != "" { + log.Printf("[DEBUG] ElastiCache: checking given state (%s) of cluster (%s) against cluster status (%s)", givenState, clusterID, *c.CacheClusterStatus) // check to make sure we have the node count we're expecting if int64(len(c.CacheNodes)) != *c.NumCacheNodes { log.Printf("[DEBUG] Node count is not what is expected: %d found, %d expected", len(c.CacheNodes), *c.NumCacheNodes) return nil, "creating", nil } + + log.Printf("[DEBUG] Node count matched (%d)", len(c.CacheNodes)) // loop the nodes and check their status as well for _, n := range c.CacheNodes { + log.Printf("[DEBUG] Checking cache node for status: %s", n) if n.CacheNodeStatus != nil && *n.CacheNodeStatus != "available" { log.Printf("[DEBUG] Node (%s) is not yet available, status: %s", *n.CacheNodeID, *n.CacheNodeStatus) return nil, "creating", nil } + log.Printf("[DEBUG] Cache node not in expected state") } + log.Printf("[DEBUG] ElastiCache returning given state (%s), cluster: %s", givenState, c) return c, givenState, nil } log.Printf("[DEBUG] current status: %v", *c.CacheClusterStatus) From 38ce950b4cda0bf538a2b9b4848f93d5e312bad3 Mon Sep 17 00:00:00 2001 From: Clint Date: Fri, 24 Jul 2015 12:01:06 -0500 Subject: [PATCH 35/73] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cec80916..6b0351cf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ IMPROVEMENTS: * provider/aws: Added website_domain for S3 buckets [GH-2210] * provider/aws: ELB names are now optional, and generated by Terraform if omitted [GH-2571] * provider/aws: Added `source_dest_check` attribute to the aws_network_interface [GH-2741] + * provider/aws: Clean up externally removed Launch Configurations [GH-2806] BUG FIXES: From dfe0efaf175653b7ea34a6776a9b882e055f060b Mon Sep 17 00:00:00 2001 From: Christopher Tiwald Date: Thu, 16 Jul 2015 01:37:21 -0400 Subject: [PATCH 36/73] aws_db_instance: Only write lowercase engines to the state file. Amazon accepts mixed-case engines, but only returns lowercase. Without the proper StateFunc, every apply of a mixed-case engine will result in a new db instance. Standardize on lowercase. --- builtin/providers/aws/resource_aws_db_instance.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builtin/providers/aws/resource_aws_db_instance.go b/builtin/providers/aws/resource_aws_db_instance.go index 47a98b73d..6ca1916b5 100644 --- a/builtin/providers/aws/resource_aws_db_instance.go +++ b/builtin/providers/aws/resource_aws_db_instance.go @@ -46,6 +46,10 @@ func resourceAwsDbInstance() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, + StateFunc: func(v interface{}) string { + value := v.(string) + return strings.ToLower(value) + }, }, "engine_version": &schema.Schema{ From 4f085ba550fcebaf5c57ca6cf1deab27351eea70 Mon Sep 17 00:00:00 2001 From: Christopher Tiwald Date: Thu, 16 Jul 2015 01:39:23 -0400 Subject: [PATCH 37/73] aws_db_instance: Add mixed-case engine test to ensure StateFunc works. --- builtin/providers/aws/resource_aws_db_instance_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_db_instance_test.go b/builtin/providers/aws/resource_aws_db_instance_test.go index ef1931b03..b60a01da9 100644 --- a/builtin/providers/aws/resource_aws_db_instance_test.go +++ b/builtin/providers/aws/resource_aws_db_instance_test.go @@ -176,7 +176,7 @@ resource "aws_db_instance" "bar" { identifier = "foobarbaz-test-terraform-%d" allocated_storage = 10 - engine = "mysql" + engine = "MySQL" engine_version = "5.6.21" instance_class = "db.t1.micro" name = "baz" From 6931e8520e75026606641cdf4704fb2fce4976e0 Mon Sep 17 00:00:00 2001 From: Tom Hummel Date: Sat, 25 Jul 2015 12:49:10 -0700 Subject: [PATCH 38/73] aws_sqs_queue argument description fix the descriptions of `delay_seconds` and `visibility_timeout_seconds` appear to be swapped. --- website/source/docs/providers/aws/r/sqs_queue.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/source/docs/providers/aws/r/sqs_queue.html.markdown b/website/source/docs/providers/aws/r/sqs_queue.html.markdown index a3bf25c57..74ae201f2 100644 --- a/website/source/docs/providers/aws/r/sqs_queue.html.markdown +++ b/website/source/docs/providers/aws/r/sqs_queue.html.markdown @@ -25,10 +25,10 @@ resource "aws_sqs_queue" "terraform_queue" { The following arguments are supported: * `name` - (Required) This is the human-readable name of the queue -* `visibility_timeout_seconds` - (Optional) The time in seconds that the delivery of all messages in the queue will be delayed. An integer from 0 to 900 (15 minutes). The default for this attribute is 30 seconds +* `visibility_timeout_seconds` - (Optional) The visibility timeout for the queue. An integer from 0 to 43200 (12 hours). The default for this attribute is 30. For more information about visibility timeout see AWS docs. * `message_retention_seconds` - (Optional) The number of seconds Amazon SQS retains a message. Integer representing seconds, from 60 (1 minute) to 1209600 (14 days). The default for this attribute is 345600 (4 days). * `max_message_size` - (Optional) The limit of how many bytes a message can contain before Amazon SQS rejects it. An integer from 1024 bytes (1 KiB) up to 262144 bytes (256 KiB). The default for this attribute is 262144 (256 KiB). -* `delay_seconds` - (Optional) The visibility timeout for the queue. An integer from 0 to 43200 (12 hours). The default for this attribute is 30. For more information about visibility timeout. +* `delay_seconds` - (Optional) The time in seconds that the delivery of all messages in the queue will be delayed. An integer from 0 to 900 (15 minutes). The default for this attribute is 30 seconds. * `receive_wait_time_seconds` - (Optional) The time for which a ReceiveMessage call will wait for a message to arrive (long polling) before returning. An integer from 0 to 20 (seconds). The default for this attribute is 0, meaning that the call will return immediately. * `policy` - (Optional) The JSON policy for the SQS queue From a32eebfd251604f0cd552ef2675a6275aa62d4ea Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Mon, 27 Jul 2015 13:36:17 +0200 Subject: [PATCH 39/73] [Vagrantfile] set the hostname to 'terraform' --- Vagrantfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Vagrantfile b/Vagrantfile index 3017ff58c..259193729 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -42,6 +42,7 @@ SCRIPT Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "chef/ubuntu-12.04" + config.vm.hostname = "terraform" config.vm.provision "shell", inline: $script, privileged: false config.vm.synced_folder '.', '/opt/gopath/src/github.com/hashicorp/terraform' From 6c86ae3a191c92c37c8330ec121dda0072e0bfe8 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Mon, 27 Jul 2015 16:14:01 +0100 Subject: [PATCH 40/73] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b0351cf1..9ea5104ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ IMPROVEMENTS: + * core: Add resource IDs to errors coming from `apply`/`refresh` [GH-2815] * provider/aws: Validate credentials before walking the graph [GH-2730] * provider/aws: Added website_domain for S3 buckets [GH-2210] * provider/aws: ELB names are now optional, and generated by Terraform if omitted [GH-2571] @@ -10,6 +11,7 @@ IMPROVEMENTS: BUG FIXES: + * core: Prevent error duplication in `apply` [GH-2815] * provider/aws: Fix issue with toggling monitoring in AWS Instances [GH-2794] * provider/aws: Fix issue with Spot Instance Requests and cancellation [GH-2805] From de74608d37c8518da857d215140d8232a95d9d03 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Mon, 27 Jul 2015 10:22:35 -0500 Subject: [PATCH 41/73] provider/azure: Note to Instance docs about some images requiring a Storage Service --- website/source/docs/providers/azure/r/instance.html.markdown | 3 ++- .../docs/providers/azure/r/storage_service.html.markdown | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/website/source/docs/providers/azure/r/instance.html.markdown b/website/source/docs/providers/azure/r/instance.html.markdown index 6b9428762..f983c622a 100644 --- a/website/source/docs/providers/azure/r/instance.html.markdown +++ b/website/source/docs/providers/azure/r/instance.html.markdown @@ -72,7 +72,8 @@ The following arguments are supported: * `storage_service_name` - (Optional) The name of an existing storage account within the subscription which will be used to store the VHDs of this - instance. Changing this forces a new resource to be created. + instance. Changing this forces a new resource to be created. **A Storage + Service is required if you are using a Platform Image** * `reverse_dns` - (Optional) The DNS address to which the IP address of the hosted service resolves when queried using a reverse DNS query. Changing diff --git a/website/source/docs/providers/azure/r/storage_service.html.markdown b/website/source/docs/providers/azure/r/storage_service.html.markdown index 6000817de..213965f99 100644 --- a/website/source/docs/providers/azure/r/storage_service.html.markdown +++ b/website/source/docs/providers/azure/r/storage_service.html.markdown @@ -26,7 +26,7 @@ resource "azure_storage_service" "tfstor" { The following arguments are supported: * `name` - (Required) The name of the storage service. Must be between 4 and 24 - lowercase-only characters or digits Must be unique on Azure. + lowercase-only characters or digits. Must be unique on Azure. * `location` - (Required) The location where the storage service should be created. For a list of all Azure locations, please consult [this link](http://azure.microsoft.com/en-us/regions/). From 493b31d1225c6b8e962dee891c89935258ca4dca Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Mon, 27 Jul 2015 10:23:42 -0500 Subject: [PATCH 42/73] provider/azure: Trap a specific Platform Image error in a new PlatformStorageError --- builtin/providers/azure/errors.go | 5 +++++ builtin/providers/azure/resource_azure_instance.go | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 builtin/providers/azure/errors.go diff --git a/builtin/providers/azure/errors.go b/builtin/providers/azure/errors.go new file mode 100644 index 000000000..89fa6e4b3 --- /dev/null +++ b/builtin/providers/azure/errors.go @@ -0,0 +1,5 @@ +package azure + +import "errors" + +var PlatformStorageError = errors.New("When using a platform image, the 'storage' parameter is required") diff --git a/builtin/providers/azure/resource_azure_instance.go b/builtin/providers/azure/resource_azure_instance.go index b273675f5..5ade3b55d 100644 --- a/builtin/providers/azure/resource_azure_instance.go +++ b/builtin/providers/azure/resource_azure_instance.go @@ -591,6 +591,10 @@ func retrieveImageDetails( return configureForImage, osType, nil } + if err == PlatformStorageError { + return nil, "", err + } + return nil, "", fmt.Errorf("Could not find image with label '%s'. Available images are: %s", label, strings.Join(append(VMLabels, OSLabels...), ", ")) } @@ -647,7 +651,7 @@ func retrieveOSImageDetails( if img.MediaLink == "" { if storage == "" { return nil, "", nil, - fmt.Errorf("When using a platform image, the 'storage' parameter is required") + PlatformStorageError } img.MediaLink = fmt.Sprintf(osDiskBlobStorageURL, storage, name) } From 99f9b93b575e33273241ff08e58c589ba07819ba Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Tue, 7 Jul 2015 15:12:41 -0600 Subject: [PATCH 43/73] provider/aws: Error when unable to find a Root Block Device name Fixes #2633 --- builtin/providers/aws/resource_aws_instance.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go index 6d6657c15..d6ec35af1 100644 --- a/builtin/providers/aws/resource_aws_instance.go +++ b/builtin/providers/aws/resource_aws_instance.go @@ -778,6 +778,10 @@ func fetchRootDeviceName(ami string, conn *ec2.EC2) (*string, error) { rootDeviceName = image.BlockDeviceMappings[0].DeviceName } + if rootDeviceName == nil { + return nil, fmt.Errorf("[WARN] Error finding Root Device Name for AMI (%s)", ami) + } + return rootDeviceName, nil } From 2b082166866305cf4ae72a8baa564076933435ac Mon Sep 17 00:00:00 2001 From: Clint Date: Mon, 27 Jul 2015 12:22:23 -0500 Subject: [PATCH 44/73] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ea5104ef..952ab4b07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ BUG FIXES: * core: Prevent error duplication in `apply` [GH-2815] * provider/aws: Fix issue with toggling monitoring in AWS Instances [GH-2794] * provider/aws: Fix issue with Spot Instance Requests and cancellation [GH-2805] + * provider/aws: Fixx issue when unable to find a Root Block Device name of an Instance Backed + AMI [GH-2646] ## 0.6.1 (July 20, 2015) From 5c7d22efcdc54f7982e13a76ada5b91bd9529fb4 Mon Sep 17 00:00:00 2001 From: Clint Date: Mon, 27 Jul 2015 14:28:47 -0500 Subject: [PATCH 45/73] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 952ab4b07..a548f290e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ IMPROVEMENTS: * provider/aws: Validate credentials before walking the graph [GH-2730] * provider/aws: Added website_domain for S3 buckets [GH-2210] * provider/aws: ELB names are now optional, and generated by Terraform if omitted [GH-2571] + * provider/aws: Downcase RDS engine names to prevent continuous diffs [GH-2745] * provider/aws: Added `source_dest_check` attribute to the aws_network_interface [GH-2741] * provider/aws: Clean up externally removed Launch Configurations [GH-2806] From affa09efdd6f2bb628bcc3266d329bbba96fc0f4 Mon Sep 17 00:00:00 2001 From: Jesse Szwedko Date: Wed, 15 Jul 2015 19:09:35 +0000 Subject: [PATCH 46/73] Compute private ip addresses of ENIs if they are not specified As AWS will assign the ENI an address --- .../aws/resource_aws_network_interface.go | 1 + .../resource_aws_network_interface_test.go | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/builtin/providers/aws/resource_aws_network_interface.go b/builtin/providers/aws/resource_aws_network_interface.go index 2cf7b13c3..a26e668d9 100644 --- a/builtin/providers/aws/resource_aws_network_interface.go +++ b/builtin/providers/aws/resource_aws_network_interface.go @@ -34,6 +34,7 @@ func resourceAwsNetworkInterface() *schema.Resource { Type: schema.TypeSet, Optional: true, ForceNew: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, diff --git a/builtin/providers/aws/resource_aws_network_interface_test.go b/builtin/providers/aws/resource_aws_network_interface_test.go index a444a0136..65af4418c 100644 --- a/builtin/providers/aws/resource_aws_network_interface_test.go +++ b/builtin/providers/aws/resource_aws_network_interface_test.go @@ -77,6 +77,26 @@ func TestAccAWSENI_sourceDestCheck(t *testing.T) { }) } +func TestAccAWSENI_computedIPs(t *testing.T) { + var conf ec2.NetworkInterface + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSENIDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAWSENIConfigWithNoPrivateIPs, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSENIExists("aws_network_interface.bar", &conf), + resource.TestCheckResourceAttr( + "aws_network_interface.bar", "private_ips.#", "1"), + ), + }, + }, + }) +} + func testAccCheckAWSENIExists(n string, res *ec2.NetworkInterface) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -243,6 +263,23 @@ resource "aws_network_interface" "bar" { } ` +const testAccAWSENIConfigWithNoPrivateIPs = ` +resource "aws_vpc" "foo" { + cidr_block = "172.16.0.0/16" +} + +resource "aws_subnet" "foo" { + vpc_id = "${aws_vpc.foo.id}" + cidr_block = "172.16.10.0/24" + availability_zone = "us-west-2a" +} + +resource "aws_network_interface" "bar" { + subnet_id = "${aws_subnet.foo.id}" + source_dest_check = false +} +` + const testAccAWSENIConfigWithAttachment = ` resource "aws_vpc" "foo" { cidr_block = "172.16.0.0/16" From 1ec247ef376e8d37b056d97f24fa3cc56b29da15 Mon Sep 17 00:00:00 2001 From: Dave Cunningham Date: Mon, 27 Jul 2015 20:47:10 -0400 Subject: [PATCH 47/73] Use new autoscaler / instance group manager APIs. --- builtin/providers/google/config.go | 18 ---- builtin/providers/google/operation.go | 96 +------------------ builtin/providers/google/provider.go | 4 +- ...aler.go => resource_compute_autoscaler.go} | 71 +++++++------- ...go => resource_compute_autoscaler_test.go} | 36 +++---- ...esource_compute_instance_group_manager.go} | 90 ++++++++--------- ...ce_compute_instance_group_manager_test.go} | 64 +++++-------- ...resource_compute_instance_template_test.go | 4 +- ...kdown => compute_autoscaler.html.markdown} | 17 ++-- ...pute_instance_group_manager.html.markdown} | 13 +-- website/source/layouts/google.erb | 8 +- 11 files changed, 136 insertions(+), 285 deletions(-) rename builtin/providers/google/{resource_autoscaler.go => resource_compute_autoscaler.go} (79%) rename builtin/providers/google/{resource_autoscaler_test.go => resource_compute_autoscaler_test.go} (83%) rename builtin/providers/google/{resource_replicapool_instance_group_manager.go => resource_compute_instance_group_manager.go} (68%) rename builtin/providers/google/{resource_replicapool_instance_group_manager_test.go => resource_compute_instance_group_manager_test.go} (80%) rename website/source/docs/providers/google/r/{autoscaler.html.markdown => compute_autoscaler.html.markdown} (90%) rename website/source/docs/providers/google/r/{replicapool_instance_group_manager.html.markdown => compute_instance_group_manager.html.markdown} (84%) diff --git a/builtin/providers/google/config.go b/builtin/providers/google/config.go index 189653cf6..6af5fbd61 100644 --- a/builtin/providers/google/config.go +++ b/builtin/providers/google/config.go @@ -14,11 +14,9 @@ import ( "golang.org/x/oauth2" "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" - "google.golang.org/api/autoscaler/v1beta2" "google.golang.org/api/compute/v1" "google.golang.org/api/container/v1" "google.golang.org/api/dns/v1" - "google.golang.org/api/replicapool/v1beta2" "google.golang.org/api/storage/v1" ) @@ -29,11 +27,9 @@ type Config struct { Project string Region string - clientAutoscaler *autoscaler.Service clientCompute *compute.Service clientContainer *container.Service clientDns *dns.Service - clientReplicaPool *replicapool.Service clientStorage *storage.Service } @@ -132,20 +128,6 @@ func (c *Config) loadAndValidate() error { } c.clientDns.UserAgent = userAgent - log.Printf("[INFO] Instantiating Google Replica Pool client...") - c.clientReplicaPool, err = replicapool.New(client) - if err != nil { - return err - } - c.clientReplicaPool.UserAgent = userAgent - - log.Printf("[INFO] Instantiating Google Autoscaler client...") - c.clientAutoscaler, err = autoscaler.New(client) - if err != nil { - return err - } - c.clientAutoscaler.UserAgent = userAgent - log.Printf("[INFO] Instantiating Google Storage Client...") c.clientStorage, err = storage.New(client) if err != nil { diff --git a/builtin/providers/google/operation.go b/builtin/providers/google/operation.go index 9d11668ba..aef4576c4 100644 --- a/builtin/providers/google/operation.go +++ b/builtin/providers/google/operation.go @@ -4,9 +4,7 @@ import ( "bytes" "fmt" - "google.golang.org/api/autoscaler/v1beta2" "google.golang.org/api/compute/v1" - "google.golang.org/api/replicapool/v1beta2" "github.com/hashicorp/terraform/helper/resource" ) @@ -26,8 +24,8 @@ type OperationWaiter struct { Op *compute.Operation Project string Region string - Zone string Type OperationWaitType + Zone string } func (w *OperationWaiter) RefreshFunc() resource.StateRefreshFunc { @@ -80,95 +78,3 @@ func (e OperationError) Error() string { return buf.String() } -// Replicapool Operations -type ReplicaPoolOperationWaiter struct { - Service *replicapool.Service - Op *replicapool.Operation - Project string - Region string - Zone string -} - -func (w *ReplicaPoolOperationWaiter) RefreshFunc() resource.StateRefreshFunc { - return func() (interface{}, string, error) { - var op *replicapool.Operation - var err error - - op, err = w.Service.ZoneOperations.Get( - w.Project, w.Zone, w.Op.Name).Do() - - if err != nil { - return nil, "", err - } - - return op, op.Status, nil - } -} - -func (w *ReplicaPoolOperationWaiter) Conf() *resource.StateChangeConf { - return &resource.StateChangeConf{ - Pending: []string{"PENDING", "RUNNING"}, - Target: "DONE", - Refresh: w.RefreshFunc(), - } -} - -// ReplicaPoolOperationError wraps replicapool.OperationError and implements the -// error interface so it can be returned. -type ReplicaPoolOperationError replicapool.OperationError - -func (e ReplicaPoolOperationError) Error() string { - var buf bytes.Buffer - - for _, err := range e.Errors { - buf.WriteString(err.Message + "\n") - } - - return buf.String() -} - -// Autoscaler Operations -type AutoscalerOperationWaiter struct { - Service *autoscaler.Service - Op *autoscaler.Operation - Project string - Zone string -} - -func (w *AutoscalerOperationWaiter) RefreshFunc() resource.StateRefreshFunc { - return func() (interface{}, string, error) { - var op *autoscaler.Operation - var err error - - op, err = w.Service.ZoneOperations.Get( - w.Project, w.Zone, w.Op.Name).Do() - - if err != nil { - return nil, "", err - } - - return op, op.Status, nil - } -} - -func (w *AutoscalerOperationWaiter) Conf() *resource.StateChangeConf { - return &resource.StateChangeConf{ - Pending: []string{"PENDING", "RUNNING"}, - Target: "DONE", - Refresh: w.RefreshFunc(), - } -} - -// AutoscalerOperationError wraps autoscaler.OperationError and implements the -// error interface so it can be returned. -type AutoscalerOperationError autoscaler.OperationError - -func (e AutoscalerOperationError) Error() string { - var buf bytes.Buffer - - for _, err := range e.Errors { - buf.WriteString(err.Message + "\n") - } - - return buf.String() -} diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index c38b736e3..30cef8c1b 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -29,7 +29,7 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ - "google_autoscaler": resourceAutoscaler(), + "google_compute_autoscaler": resourceComputeAutoscaler(), "google_compute_address": resourceComputeAddress(), "google_compute_disk": resourceComputeDisk(), "google_compute_firewall": resourceComputeFirewall(), @@ -43,7 +43,7 @@ func Provider() terraform.ResourceProvider { "google_container_cluster": resourceContainerCluster(), "google_dns_managed_zone": resourceDnsManagedZone(), "google_dns_record_set": resourceDnsRecordSet(), - "google_replicapool_instance_group_manager": resourceReplicaPoolInstanceGroupManager(), + "google_compute_instance_group_manager": resourceComputeInstanceGroupManager(), "google_storage_bucket": resourceStorageBucket(), }, diff --git a/builtin/providers/google/resource_autoscaler.go b/builtin/providers/google/resource_compute_autoscaler.go similarity index 79% rename from builtin/providers/google/resource_autoscaler.go rename to builtin/providers/google/resource_compute_autoscaler.go index 23d7b33a4..35c8167ff 100644 --- a/builtin/providers/google/resource_autoscaler.go +++ b/builtin/providers/google/resource_compute_autoscaler.go @@ -6,16 +6,16 @@ import ( "time" "google.golang.org/api/googleapi" - "google.golang.org/api/autoscaler/v1beta2" + "google.golang.org/api/compute/v1" "github.com/hashicorp/terraform/helper/schema" ) -func resourceAutoscaler() *schema.Resource { +func resourceComputeAutoscaler() *schema.Resource { return &schema.Resource{ - Create: resourceAutoscalerCreate, - Read: resourceAutoscalerRead, - Update: resourceAutoscalerUpdate, - Delete: resourceAutoscalerDelete, + Create: resourceComputeAutoscalerCreate, + Read: resourceComputeAutoscalerRead, + Update: resourceComputeAutoscalerUpdate, + Delete: resourceComputeAutoscalerDelete, Schema: map[string]*schema.Schema{ "name": &schema.Schema{ @@ -120,10 +120,10 @@ func resourceAutoscaler() *schema.Resource { } } -func buildAutoscaler(d *schema.ResourceData) (*autoscaler.Autoscaler, error) { +func buildAutoscaler(d *schema.ResourceData) (*compute.Autoscaler, error) { // Build the parameter - scaler := &autoscaler.Autoscaler{ + scaler := &compute.Autoscaler{ Name: d.Get("name").(string), Target: d.Get("target").(string), } @@ -140,7 +140,7 @@ func buildAutoscaler(d *schema.ResourceData) (*autoscaler.Autoscaler, error) { prefix := "autoscaling_policy.0." - scaler.AutoscalingPolicy = &autoscaler.AutoscalingPolicy{ + scaler.AutoscalingPolicy = &compute.AutoscalingPolicy{ MaxNumReplicas: int64(d.Get(prefix + "max_replicas").(int)), MinNumReplicas: int64(d.Get(prefix + "min_replicas").(int)), CoolDownPeriodSec: int64(d.Get(prefix + "cooldown_period").(int)), @@ -156,7 +156,7 @@ func buildAutoscaler(d *schema.ResourceData) (*autoscaler.Autoscaler, error) { return nil, fmt.Errorf("The autoscaling_policy must have exactly one cpu_utilization, found %d.", cpuUtilCount) } policyCounter++ - scaler.AutoscalingPolicy.CpuUtilization = &autoscaler.AutoscalingPolicyCpuUtilization{ + scaler.AutoscalingPolicy.CpuUtilization = &compute.AutoscalingPolicyCpuUtilization{ UtilizationTarget: d.Get(prefix + "cpu_utilization.0.target").(float64), } } @@ -168,7 +168,7 @@ func buildAutoscaler(d *schema.ResourceData) (*autoscaler.Autoscaler, error) { if metricCount != 1 { return nil, fmt.Errorf("The autoscaling_policy must have exactly one metric, found %d.", metricCount) } - scaler.AutoscalingPolicy.CustomMetricUtilizations = []*autoscaler.AutoscalingPolicyCustomMetricUtilization{ + scaler.AutoscalingPolicy.CustomMetricUtilizations = []*compute.AutoscalingPolicyCustomMetricUtilization{ { Metric: d.Get(prefix + "metric.0.name").(string), UtilizationTarget: d.Get(prefix + "metric.0.target").(float64), @@ -185,7 +185,7 @@ func buildAutoscaler(d *schema.ResourceData) (*autoscaler.Autoscaler, error) { if lbuCount != 1 { return nil, fmt.Errorf("The autoscaling_policy must have exactly one load_balancing_utilization, found %d.", lbuCount) } - scaler.AutoscalingPolicy.LoadBalancingUtilization = &autoscaler.AutoscalingPolicyLoadBalancingUtilization{ + scaler.AutoscalingPolicy.LoadBalancingUtilization = &compute.AutoscalingPolicyLoadBalancingUtilization{ UtilizationTarget: d.Get(prefix + "load_balancing_utilization.0.target").(float64), } } @@ -198,7 +198,7 @@ func buildAutoscaler(d *schema.ResourceData) (*autoscaler.Autoscaler, error) { return scaler, nil } -func resourceAutoscalerCreate(d *schema.ResourceData, meta interface{}) error { +func resourceComputeAutoscalerCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) // Get the zone @@ -215,7 +215,7 @@ func resourceAutoscalerCreate(d *schema.ResourceData, meta interface{}) error { return err } - op, err := config.clientAutoscaler.Autoscalers.Insert( + op, err := config.clientCompute.Autoscalers.Insert( config.Project, zone.Name, scaler).Do() if err != nil { return fmt.Errorf("Error creating Autoscaler: %s", err) @@ -225,10 +225,11 @@ func resourceAutoscalerCreate(d *schema.ResourceData, meta interface{}) error { d.SetId(scaler.Name) // Wait for the operation to complete - w := &AutoscalerOperationWaiter{ - Service: config.clientAutoscaler, + w := &OperationWaiter{ + Service: config.clientCompute, Op: op, Project: config.Project, + Type: OperationWaitZone, Zone: zone.Name, } state := w.Conf() @@ -238,23 +239,23 @@ func resourceAutoscalerCreate(d *schema.ResourceData, meta interface{}) error { if err != nil { return fmt.Errorf("Error waiting for Autoscaler to create: %s", err) } - op = opRaw.(*autoscaler.Operation) + op = opRaw.(*compute.Operation) if op.Error != nil { // The resource didn't actually create d.SetId("") // Return the error - return AutoscalerOperationError(*op.Error) + return OperationError(*op.Error) } - return resourceAutoscalerRead(d, meta) + return resourceComputeAutoscalerRead(d, meta) } -func resourceAutoscalerRead(d *schema.ResourceData, meta interface{}) error { +func resourceComputeAutoscalerRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) zone := d.Get("zone").(string) - scaler, err := config.clientAutoscaler.Autoscalers.Get( + scaler, err := config.clientCompute.Autoscalers.Get( config.Project, zone, d.Id()).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { @@ -272,7 +273,7 @@ func resourceAutoscalerRead(d *schema.ResourceData, meta interface{}) error { return nil } -func resourceAutoscalerUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceComputeAutoscalerUpdate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) zone := d.Get("zone").(string) @@ -282,7 +283,7 @@ func resourceAutoscalerUpdate(d *schema.ResourceData, meta interface{}) error { return err } - op, err := config.clientAutoscaler.Autoscalers.Patch( + op, err := config.clientCompute.Autoscalers.Patch( config.Project, zone, d.Id(), scaler).Do() if err != nil { return fmt.Errorf("Error updating Autoscaler: %s", err) @@ -292,10 +293,11 @@ func resourceAutoscalerUpdate(d *schema.ResourceData, meta interface{}) error { d.SetId(scaler.Name) // Wait for the operation to complete - w := &AutoscalerOperationWaiter{ - Service: config.clientAutoscaler, + w := &OperationWaiter{ + Service: config.clientCompute, Op: op, Project: config.Project, + Type: OperationWaitZone, Zone: zone, } state := w.Conf() @@ -305,30 +307,31 @@ func resourceAutoscalerUpdate(d *schema.ResourceData, meta interface{}) error { if err != nil { return fmt.Errorf("Error waiting for Autoscaler to update: %s", err) } - op = opRaw.(*autoscaler.Operation) + op = opRaw.(*compute.Operation) if op.Error != nil { // Return the error - return AutoscalerOperationError(*op.Error) + return OperationError(*op.Error) } - return resourceAutoscalerRead(d, meta) + return resourceComputeAutoscalerRead(d, meta) } -func resourceAutoscalerDelete(d *schema.ResourceData, meta interface{}) error { +func resourceComputeAutoscalerDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) zone := d.Get("zone").(string) - op, err := config.clientAutoscaler.Autoscalers.Delete( + op, err := config.clientCompute.Autoscalers.Delete( config.Project, zone, d.Id()).Do() if err != nil { return fmt.Errorf("Error deleting autoscaler: %s", err) } // Wait for the operation to complete - w := &AutoscalerOperationWaiter{ - Service: config.clientAutoscaler, + w := &OperationWaiter{ + Service: config.clientCompute, Op: op, Project: config.Project, + Type: OperationWaitZone, Zone: zone, } state := w.Conf() @@ -338,10 +341,10 @@ func resourceAutoscalerDelete(d *schema.ResourceData, meta interface{}) error { if err != nil { return fmt.Errorf("Error waiting for Autoscaler to delete: %s", err) } - op = opRaw.(*autoscaler.Operation) + op = opRaw.(*compute.Operation) if op.Error != nil { // Return the error - return AutoscalerOperationError(*op.Error) + return OperationError(*op.Error) } d.SetId("") diff --git a/builtin/providers/google/resource_autoscaler_test.go b/builtin/providers/google/resource_compute_autoscaler_test.go similarity index 83% rename from builtin/providers/google/resource_autoscaler_test.go rename to builtin/providers/google/resource_compute_autoscaler_test.go index 1f7ad280e..fbc900510 100644 --- a/builtin/providers/google/resource_autoscaler_test.go +++ b/builtin/providers/google/resource_compute_autoscaler_test.go @@ -4,13 +4,13 @@ import ( "fmt" "testing" - "google.golang.org/api/autoscaler/v1beta2" + "google.golang.org/api/compute/v1" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) func TestAccAutoscaler_basic(t *testing.T) { - var ascaler autoscaler.Autoscaler + var ascaler compute.Autoscaler resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -21,7 +21,7 @@ func TestAccAutoscaler_basic(t *testing.T) { Config: testAccAutoscaler_basic, Check: resource.ComposeTestCheckFunc( testAccCheckAutoscalerExists( - "google_autoscaler.foobar", &ascaler), + "google_compute_autoscaler.foobar", &ascaler), ), }, }, @@ -29,7 +29,7 @@ func TestAccAutoscaler_basic(t *testing.T) { } func TestAccAutoscaler_update(t *testing.T) { - var ascaler autoscaler.Autoscaler + var ascaler compute.Autoscaler resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -40,16 +40,16 @@ func TestAccAutoscaler_update(t *testing.T) { Config: testAccAutoscaler_basic, Check: resource.ComposeTestCheckFunc( testAccCheckAutoscalerExists( - "google_autoscaler.foobar", &ascaler), + "google_compute_autoscaler.foobar", &ascaler), ), }, resource.TestStep{ Config: testAccAutoscaler_update, Check: resource.ComposeTestCheckFunc( testAccCheckAutoscalerExists( - "google_autoscaler.foobar", &ascaler), + "google_compute_autoscaler.foobar", &ascaler), testAccCheckAutoscalerUpdated( - "google_autoscaler.foobar", 10), + "google_compute_autoscaler.foobar", 10), ), }, }, @@ -60,11 +60,11 @@ func testAccCheckAutoscalerDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) for _, rs := range s.RootModule().Resources { - if rs.Type != "google_autoscaler" { + if rs.Type != "google_compute_autoscaler" { continue } - _, err := config.clientAutoscaler.Autoscalers.Get( + _, err := config.clientCompute.Autoscalers.Get( config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() if err == nil { return fmt.Errorf("Autoscaler still exists") @@ -74,7 +74,7 @@ func testAccCheckAutoscalerDestroy(s *terraform.State) error { return nil } -func testAccCheckAutoscalerExists(n string, ascaler *autoscaler.Autoscaler) resource.TestCheckFunc { +func testAccCheckAutoscalerExists(n string, ascaler *compute.Autoscaler) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -87,7 +87,7 @@ func testAccCheckAutoscalerExists(n string, ascaler *autoscaler.Autoscaler) reso config := testAccProvider.Meta().(*Config) - found, err := config.clientAutoscaler.Autoscalers.Get( + found, err := config.clientCompute.Autoscalers.Get( config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() if err != nil { return err @@ -116,7 +116,7 @@ func testAccCheckAutoscalerUpdated(n string, max int64) resource.TestCheckFunc { config := testAccProvider.Meta().(*Config) - ascaler, err := config.clientAutoscaler.Autoscalers.Get( + ascaler, err := config.clientCompute.Autoscalers.Get( config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() if err != nil { return err @@ -162,7 +162,7 @@ resource "google_compute_target_pool" "foobar" { session_affinity = "CLIENT_IP_PROTO" } -resource "google_replicapool_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "foobar" { description = "Terraform test instance group manager" name = "terraform-test-groupmanager" instance_template = "${google_compute_instance_template.foobar.self_link}" @@ -171,11 +171,11 @@ resource "google_replicapool_instance_group_manager" "foobar" { zone = "us-central1-a" } -resource "google_autoscaler" "foobar" { +resource "google_compute_autoscaler" "foobar" { description = "Resource created for Terraform acceptance testing" name = "terraform-test-ascaler" zone = "us-central1-a" - target = "${google_replicapool_instance_group_manager.foobar.self_link}" + target = "${google_compute_instance_group_manager.foobar.self_link}" autoscaling_policy = { max_replicas = 5 min_replicas = 0 @@ -219,7 +219,7 @@ resource "google_compute_target_pool" "foobar" { session_affinity = "CLIENT_IP_PROTO" } -resource "google_replicapool_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "foobar" { description = "Terraform test instance group manager" name = "terraform-test-groupmanager" instance_template = "${google_compute_instance_template.foobar.self_link}" @@ -228,11 +228,11 @@ resource "google_replicapool_instance_group_manager" "foobar" { zone = "us-central1-a" } -resource "google_autoscaler" "foobar" { +resource "google_compute_autoscaler" "foobar" { description = "Resource created for Terraform acceptance testing" name = "terraform-test-ascaler" zone = "us-central1-a" - target = "${google_replicapool_instance_group_manager.foobar.self_link}" + target = "${google_compute_instance_group_manager.foobar.self_link}" autoscaling_policy = { max_replicas = 10 min_replicas = 0 diff --git a/builtin/providers/google/resource_replicapool_instance_group_manager.go b/builtin/providers/google/resource_compute_instance_group_manager.go similarity index 68% rename from builtin/providers/google/resource_replicapool_instance_group_manager.go rename to builtin/providers/google/resource_compute_instance_group_manager.go index b58f24782..a07f010e0 100644 --- a/builtin/providers/google/resource_replicapool_instance_group_manager.go +++ b/builtin/providers/google/resource_compute_instance_group_manager.go @@ -6,18 +6,18 @@ import ( "time" "google.golang.org/api/googleapi" - "google.golang.org/api/replicapool/v1beta2" + "google.golang.org/api/compute/v1" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" ) -func resourceReplicaPoolInstanceGroupManager() *schema.Resource { +func resourceComputeInstanceGroupManager() *schema.Resource { return &schema.Resource{ - Create: resourceReplicaPoolInstanceGroupManagerCreate, - Read: resourceReplicaPoolInstanceGroupManagerRead, - Update: resourceReplicaPoolInstanceGroupManagerUpdate, - Delete: resourceReplicaPoolInstanceGroupManagerDelete, + Create: resourceComputeInstanceGroupManagerCreate, + Read: resourceComputeInstanceGroupManagerRead, + Update: resourceComputeInstanceGroupManagerUpdate, + Delete: resourceComputeInstanceGroupManagerDelete, Schema: map[string]*schema.Schema{ "name": &schema.Schema{ @@ -38,17 +38,12 @@ func resourceReplicaPoolInstanceGroupManager() *schema.Resource { ForceNew: true, }, - "current_size": &schema.Schema{ - Type: schema.TypeInt, - Computed: true, - }, - "fingerprint": &schema.Schema{ Type: schema.TypeString, Computed: true, }, - "group": &schema.Schema{ + "instance_group": &schema.Schema{ Type: schema.TypeString, Computed: true, }, @@ -87,14 +82,15 @@ func resourceReplicaPoolInstanceGroupManager() *schema.Resource { } } -func waitOpZone(config *Config, op *replicapool.Operation, zone string, - resource string, action string) (*replicapool.Operation, error) { +func waitOpZone(config *Config, op *compute.Operation, zone string, + resource string, action string) (*compute.Operation, error) { - w := &ReplicaPoolOperationWaiter{ - Service: config.clientReplicaPool, + w := &OperationWaiter{ + Service: config.clientCompute, Op: op, Project: config.Project, Zone: zone, + Type: OperationWaitZone, } state := w.Conf() state.Timeout = 2 * time.Minute @@ -103,10 +99,10 @@ func waitOpZone(config *Config, op *replicapool.Operation, zone string, if err != nil { return nil, fmt.Errorf("Error waiting for %s to %s: %s", resource, action, err) } - return opRaw.(*replicapool.Operation), nil + return opRaw.(*compute.Operation), nil } -func resourceReplicaPoolInstanceGroupManagerCreate(d *schema.ResourceData, meta interface{}) error { +func resourceComputeInstanceGroupManagerCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) // Get group size, default to 1 if not given @@ -116,10 +112,11 @@ func resourceReplicaPoolInstanceGroupManagerCreate(d *schema.ResourceData, meta } // Build the parameter - manager := &replicapool.InstanceGroupManager{ + manager := &compute.InstanceGroupManager{ Name: d.Get("name").(string), BaseInstanceName: d.Get("base_instance_name").(string), InstanceTemplate: d.Get("instance_template").(string), + TargetSize: target_size, } // Set optional fields @@ -136,8 +133,8 @@ func resourceReplicaPoolInstanceGroupManagerCreate(d *schema.ResourceData, meta } log.Printf("[DEBUG] InstanceGroupManager insert request: %#v", manager) - op, err := config.clientReplicaPool.InstanceGroupManagers.Insert( - config.Project, d.Get("zone").(string), target_size, manager).Do() + op, err := config.clientCompute.InstanceGroupManagers.Insert( + config.Project, d.Get("zone").(string), manager).Do() if err != nil { return fmt.Errorf("Error creating InstanceGroupManager: %s", err) } @@ -154,16 +151,16 @@ func resourceReplicaPoolInstanceGroupManagerCreate(d *schema.ResourceData, meta // The resource didn't actually create d.SetId("") // Return the error - return ReplicaPoolOperationError(*op.Error) + return OperationError(*op.Error) } - return resourceReplicaPoolInstanceGroupManagerRead(d, meta) + return resourceComputeInstanceGroupManagerRead(d, meta) } -func resourceReplicaPoolInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error { +func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - manager, err := config.clientReplicaPool.InstanceGroupManagers.Get( + manager, err := config.clientCompute.InstanceGroupManagers.Get( config.Project, d.Get("zone").(string), d.Id()).Do() if err != nil { if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { @@ -177,15 +174,14 @@ func resourceReplicaPoolInstanceGroupManagerRead(d *schema.ResourceData, meta in } // Set computed fields - d.Set("current_size", manager.CurrentSize) d.Set("fingerprint", manager.Fingerprint) - d.Set("group", manager.Group) + d.Set("instance_group", manager.InstanceGroup) d.Set("target_size", manager.TargetSize) d.Set("self_link", manager.SelfLink) return nil } -func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) d.Partial(true) @@ -200,12 +196,12 @@ func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta } // Build the parameter - setTargetPools := &replicapool.InstanceGroupManagersSetTargetPoolsRequest{ + setTargetPools := &compute.InstanceGroupManagersSetTargetPoolsRequest{ Fingerprint: d.Get("fingerprint").(string), TargetPools: targetPools, } - op, err := config.clientReplicaPool.InstanceGroupManagers.SetTargetPools( + op, err := config.clientCompute.InstanceGroupManagers.SetTargetPools( config.Project, d.Get("zone").(string), d.Id(), setTargetPools).Do() if err != nil { return fmt.Errorf("Error updating InstanceGroupManager: %s", err) @@ -217,7 +213,7 @@ func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta return err } if op.Error != nil { - return ReplicaPoolOperationError(*op.Error) + return OperationError(*op.Error) } d.SetPartial("target_pools") @@ -226,11 +222,11 @@ func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta // If instance_template changes then update if d.HasChange("instance_template") { // Build the parameter - setInstanceTemplate := &replicapool.InstanceGroupManagersSetInstanceTemplateRequest{ + setInstanceTemplate := &compute.InstanceGroupManagersSetInstanceTemplateRequest{ InstanceTemplate: d.Get("instance_template").(string), } - op, err := config.clientReplicaPool.InstanceGroupManagers.SetInstanceTemplate( + op, err := config.clientCompute.InstanceGroupManagers.SetInstanceTemplate( config.Project, d.Get("zone").(string), d.Id(), setInstanceTemplate).Do() if err != nil { return fmt.Errorf("Error updating InstanceGroupManager: %s", err) @@ -242,7 +238,7 @@ func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta return err } if op.Error != nil { - return ReplicaPoolOperationError(*op.Error) + return OperationError(*op.Error) } d.SetPartial("instance_template") @@ -254,7 +250,7 @@ func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta // Only do anything if the new size is set target_size := int64(v.(int)) - op, err := config.clientReplicaPool.InstanceGroupManagers.Resize( + op, err := config.clientCompute.InstanceGroupManagers.Resize( config.Project, d.Get("zone").(string), d.Id(), target_size).Do() if err != nil { return fmt.Errorf("Error updating InstanceGroupManager: %s", err) @@ -266,7 +262,7 @@ func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta return err } if op.Error != nil { - return ReplicaPoolOperationError(*op.Error) + return OperationError(*op.Error) } } @@ -275,39 +271,29 @@ func resourceReplicaPoolInstanceGroupManagerUpdate(d *schema.ResourceData, meta d.Partial(false) - return resourceReplicaPoolInstanceGroupManagerRead(d, meta) + return resourceComputeInstanceGroupManagerRead(d, meta) } -func resourceReplicaPoolInstanceGroupManagerDelete(d *schema.ResourceData, meta interface{}) error { +func resourceComputeInstanceGroupManagerDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) zone := d.Get("zone").(string) - op, err := config.clientReplicaPool.InstanceGroupManagers.Delete(config.Project, zone, d.Id()).Do() + op, err := config.clientCompute.InstanceGroupManagers.Delete(config.Project, zone, d.Id()).Do() if err != nil { return fmt.Errorf("Error deleting instance group manager: %s", err) } // Wait for the operation to complete - w := &ReplicaPoolOperationWaiter{ - Service: config.clientReplicaPool, - Op: op, - Project: config.Project, - Zone: d.Get("zone").(string), - } - state := w.Conf() - state.Timeout = 2 * time.Minute - state.MinTimeout = 1 * time.Second - opRaw, err := state.WaitForState() + op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "delete") if err != nil { - return fmt.Errorf("Error waiting for InstanceGroupManager to delete: %s", err) + return err } - op = opRaw.(*replicapool.Operation) if op.Error != nil { // The resource didn't actually create d.SetId("") // Return the error - return ReplicaPoolOperationError(*op.Error) + return OperationError(*op.Error) } d.SetId("") diff --git a/builtin/providers/google/resource_replicapool_instance_group_manager_test.go b/builtin/providers/google/resource_compute_instance_group_manager_test.go similarity index 80% rename from builtin/providers/google/resource_replicapool_instance_group_manager_test.go rename to builtin/providers/google/resource_compute_instance_group_manager_test.go index cd5b9442e..a623b9d0b 100644 --- a/builtin/providers/google/resource_replicapool_instance_group_manager_test.go +++ b/builtin/providers/google/resource_compute_instance_group_manager_test.go @@ -4,14 +4,14 @@ import ( "fmt" "testing" - "google.golang.org/api/replicapool/v1beta2" + "google.golang.org/api/compute/v1" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) func TestAccInstanceGroupManager_basic(t *testing.T) { - var manager replicapool.InstanceGroupManager + var manager compute.InstanceGroupManager resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -22,7 +22,7 @@ func TestAccInstanceGroupManager_basic(t *testing.T) { Config: testAccInstanceGroupManager_basic, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceGroupManagerExists( - "google_replicapool_instance_group_manager.foobar", &manager), + "google_compute_instance_group_manager.foobar", &manager), ), }, }, @@ -30,7 +30,7 @@ func TestAccInstanceGroupManager_basic(t *testing.T) { } func TestAccInstanceGroupManager_update(t *testing.T) { - var manager replicapool.InstanceGroupManager + var manager compute.InstanceGroupManager resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -41,23 +41,23 @@ func TestAccInstanceGroupManager_update(t *testing.T) { Config: testAccInstanceGroupManager_basic, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceGroupManagerExists( - "google_replicapool_instance_group_manager.foobar", &manager), + "google_compute_instance_group_manager.foobar", &manager), ), }, resource.TestStep{ Config: testAccInstanceGroupManager_update, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceGroupManagerExists( - "google_replicapool_instance_group_manager.foobar", &manager), + "google_compute_instance_group_manager.foobar", &manager), ), }, resource.TestStep{ Config: testAccInstanceGroupManager_update2, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceGroupManagerExists( - "google_replicapool_instance_group_manager.foobar", &manager), + "google_compute_instance_group_manager.foobar", &manager), testAccCheckInstanceGroupManagerUpdated( - "google_replicapool_instance_group_manager.foobar", 3, + "google_compute_instance_group_manager.foobar", 3, "google_compute_target_pool.foobaz", "terraform-test-foobaz"), ), }, @@ -69,10 +69,10 @@ func testAccCheckInstanceGroupManagerDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) for _, rs := range s.RootModule().Resources { - if rs.Type != "google_replicapool_instance_group_manager" { + if rs.Type != "google_compute_instance_group_manager" { continue } - _, err := config.clientReplicaPool.InstanceGroupManagers.Get( + _, err := config.clientCompute.InstanceGroupManagers.Get( config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() if err != nil { return fmt.Errorf("InstanceGroupManager still exists") @@ -82,7 +82,7 @@ func testAccCheckInstanceGroupManagerDestroy(s *terraform.State) error { return nil } -func testAccCheckInstanceGroupManagerExists(n string, manager *replicapool.InstanceGroupManager) resource.TestCheckFunc { +func testAccCheckInstanceGroupManagerExists(n string, manager *compute.InstanceGroupManager) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -95,7 +95,7 @@ func testAccCheckInstanceGroupManagerExists(n string, manager *replicapool.Insta config := testAccProvider.Meta().(*Config) - found, err := config.clientReplicaPool.InstanceGroupManagers.Get( + found, err := config.clientCompute.InstanceGroupManagers.Get( config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() if err != nil { return err @@ -124,38 +124,18 @@ func testAccCheckInstanceGroupManagerUpdated(n string, size int64, targetPool st config := testAccProvider.Meta().(*Config) - manager, err := config.clientReplicaPool.InstanceGroupManagers.Get( + manager, err := config.clientCompute.InstanceGroupManagers.Get( config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do() if err != nil { return err } - // check that total instance count is "size" - if manager.CurrentSize != size { + // Cannot check the target pool as the instance creation is asynchronous. However, can + // check the target_size. + if manager.TargetSize != size { return fmt.Errorf("instance count incorrect") } - // check that at least one instance exists in "targetpool" - tp, ok := s.RootModule().Resources[targetPool] - if !ok { - return fmt.Errorf("Not found: %s", targetPool) - } - - if tp.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } - - targetpool, err := config.clientCompute.TargetPools.Get( - config.Project, config.Region, tp.Primary.ID).Do() - if err != nil { - return err - } - - // check that total instance count is "size" - if len(targetpool.Instances) == 0 { - return fmt.Errorf("no instance in new targetpool") - } - // check that the instance template updated instanceTemplate, err := config.clientCompute.InstanceTemplates.Get( config.Project, template).Do() @@ -203,13 +183,13 @@ resource "google_compute_target_pool" "foobar" { session_affinity = "CLIENT_IP_PROTO" } -resource "google_replicapool_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "foobar" { description = "Terraform test instance group manager" name = "terraform-test" instance_template = "${google_compute_instance_template.foobar.self_link}" target_pools = ["${google_compute_target_pool.foobar.self_link}"] base_instance_name = "foobar" - zone = "us-central1-a" + zone = "us-central1-c" target_size = 2 }` @@ -276,13 +256,13 @@ resource "google_compute_target_pool" "foobaz" { session_affinity = "CLIENT_IP_PROTO" } -resource "google_replicapool_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "foobar" { description = "Terraform test instance group manager" name = "terraform-test" instance_template = "${google_compute_instance_template.foobar.self_link}" target_pools = ["${google_compute_target_pool.foobaz.self_link}"] base_instance_name = "foobar" - zone = "us-central1-a" + zone = "us-central1-c" target_size = 2 }` @@ -349,12 +329,12 @@ resource "google_compute_target_pool" "foobaz" { session_affinity = "CLIENT_IP_PROTO" } -resource "google_replicapool_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "foobar" { description = "Terraform test instance group manager" name = "terraform-test" instance_template = "${google_compute_instance_template.foobaz.self_link}" target_pools = ["${google_compute_target_pool.foobaz.self_link}"] base_instance_name = "foobar" - zone = "us-central1-a" + zone = "us-central1-c" target_size = 3 }` diff --git a/builtin/providers/google/resource_compute_instance_template_test.go b/builtin/providers/google/resource_compute_instance_template_test.go index c552b125c..c86ea2059 100644 --- a/builtin/providers/google/resource_compute_instance_template_test.go +++ b/builtin/providers/google/resource_compute_instance_template_test.go @@ -24,7 +24,7 @@ func TestAccComputeInstanceTemplate_basic(t *testing.T) { "google_compute_instance_template.foobar", &instanceTemplate), testAccCheckComputeInstanceTemplateTag(&instanceTemplate, "foo"), testAccCheckComputeInstanceTemplateMetadata(&instanceTemplate, "foo", "bar"), - testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true), + testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140814", true, true), ), }, }, @@ -64,7 +64,7 @@ func TestAccComputeInstanceTemplate_disks(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckComputeInstanceTemplateExists( "google_compute_instance_template.foobar", &instanceTemplate), - testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true), + testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140814", true, true), testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "terraform-test-foobar", false, false), ), }, diff --git a/website/source/docs/providers/google/r/autoscaler.html.markdown b/website/source/docs/providers/google/r/compute_autoscaler.html.markdown similarity index 90% rename from website/source/docs/providers/google/r/autoscaler.html.markdown rename to website/source/docs/providers/google/r/compute_autoscaler.html.markdown index 63f1753dc..6809cd10a 100644 --- a/website/source/docs/providers/google/r/autoscaler.html.markdown +++ b/website/source/docs/providers/google/r/compute_autoscaler.html.markdown @@ -1,15 +1,12 @@ --- layout: "google" -page_title: "Google: google_autoscaler" -sidebar_current: "docs-google-resource-autoscaler" +page_title: "Google: google_compute_autoscaler" +sidebar_current: "docs-google-resource-compute-autoscaler" description: |- - Managers an Instance Group within GCE. + Manages an Autoscaler within GCE. --- -# google\_autoscaler - -**Note**: This resource is in -[beta](https://cloud.google.com/terms/launch-stages). +# google\_compute\_autoscaler A Compute Engine Autoscaler automatically adds or removes virtual machines from a managed instance group based on increases or decreases in load. This allows @@ -51,7 +48,7 @@ resource "google_compute_target_pool" "foobar" { name = "foobar" } -resource "google_replicapool_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "foobar" { name = "foobar" instance_template = "${google_compute_instance_template.foobar.self_link}" target_pools = ["${google_compute_target_pool.foobar.self_link}"] @@ -59,10 +56,10 @@ resource "google_replicapool_instance_group_manager" "foobar" { zone = "us-central1-f" } -resource "google_autoscaler" "foobar" { +resource "google_compute_autoscaler" "foobar" { name = "foobar" zone = "us-central1-f" - target = "${google_replicapool_instance_group_manager.foobar.self_link}" + target = "${google_compute_instance_group_manager.foobar.self_link}" autoscaling_policy = { max_replicas = 5 min_replicas = 1 diff --git a/website/source/docs/providers/google/r/replicapool_instance_group_manager.html.markdown b/website/source/docs/providers/google/r/compute_instance_group_manager.html.markdown similarity index 84% rename from website/source/docs/providers/google/r/replicapool_instance_group_manager.html.markdown rename to website/source/docs/providers/google/r/compute_instance_group_manager.html.markdown index d4232b25c..abaed7a58 100644 --- a/website/source/docs/providers/google/r/replicapool_instance_group_manager.html.markdown +++ b/website/source/docs/providers/google/r/compute_instance_group_manager.html.markdown @@ -1,15 +1,12 @@ --- layout: "google" -page_title: "Google: google_replicapool_instance_group_manager" -sidebar_current: "docs-google-resource-instance_group_manager" +page_title: "Google: google_compute_instance_group_manager" +sidebar_current: "docs-google-resource-compute-instance_group_manager" description: |- Manages an Instance Group within GCE. --- -# google\_replicapool\_instance\_group\_manager - -**Note**: This resource is in -[beta](https://cloud.google.com/terms/launch-stages). +# google\_compute\_instance\_group\_manager The Google Compute Engine Instance Group Manager API creates and manages pools of homogeneous Compute Engine virtual machine instances from a common instance @@ -19,7 +16,7 @@ and [API](https://cloud.google.com/compute/docs/instance-groups/manager/v1beta2/ ## Example Usage ``` -resource "google_replicapool_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "foobar" { description = "Terraform test instance group manager" name = "terraform-test" instance_template = "${google_compute_instance_template.foobar.self_link}" @@ -63,6 +60,6 @@ affect existing instances. The following attributes are exported: -* `group` - The full URL of the instance group created by the manager. +* `instance_group` - The full URL of the instance group created by the manager. * `self_link` - The URL of the created resource. diff --git a/website/source/layouts/google.erb b/website/source/layouts/google.erb index 6096c144d..f26e5e0ff 100644 --- a/website/source/layouts/google.erb +++ b/website/source/layouts/google.erb @@ -65,12 +65,12 @@ google_dns_record_set - > - google_replicapool_instance_group_manager + > + google_compute_instance_group_manager - > - google_autoscaler + > + google_compute_autoscaler > From 476197f2cfd666dc09b0ecb9b0e8ddf6b38965d6 Mon Sep 17 00:00:00 2001 From: Clint Date: Tue, 28 Jul 2015 12:58:10 -0500 Subject: [PATCH 48/73] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a548f290e..4869e2e0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ IMPROVEMENTS: * provider/aws: Downcase RDS engine names to prevent continuous diffs [GH-2745] * provider/aws: Added `source_dest_check` attribute to the aws_network_interface [GH-2741] * provider/aws: Clean up externally removed Launch Configurations [GH-2806] + * provider/aws: Compute private ip addresses of ENIs if they are not specified [GH-2743] BUG FIXES: From 24167b1085e3c5cf52577bc5f61401f57635b451 Mon Sep 17 00:00:00 2001 From: Dave Cunningham Date: Tue, 28 Jul 2015 14:09:29 -0400 Subject: [PATCH 49/73] Make failure of "basic" test not interfere with success of "update" test --- ...rce_compute_instance_group_manager_test.go | 122 ++++++------------ 1 file changed, 40 insertions(+), 82 deletions(-) diff --git a/builtin/providers/google/resource_compute_instance_group_manager_test.go b/builtin/providers/google/resource_compute_instance_group_manager_test.go index a623b9d0b..d1cf89a2d 100644 --- a/builtin/providers/google/resource_compute_instance_group_manager_test.go +++ b/builtin/providers/google/resource_compute_instance_group_manager_test.go @@ -22,7 +22,7 @@ func TestAccInstanceGroupManager_basic(t *testing.T) { Config: testAccInstanceGroupManager_basic, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceGroupManagerExists( - "google_compute_instance_group_manager.foobar", &manager), + "google_compute_instance_group_manager.igm-basic", &manager), ), }, }, @@ -37,28 +37,21 @@ func TestAccInstanceGroupManager_update(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckInstanceGroupManagerDestroy, Steps: []resource.TestStep{ - resource.TestStep{ - Config: testAccInstanceGroupManager_basic, - Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceGroupManagerExists( - "google_compute_instance_group_manager.foobar", &manager), - ), - }, resource.TestStep{ Config: testAccInstanceGroupManager_update, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceGroupManagerExists( - "google_compute_instance_group_manager.foobar", &manager), + "google_compute_instance_group_manager.igm-update", &manager), ), }, resource.TestStep{ Config: testAccInstanceGroupManager_update2, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceGroupManagerExists( - "google_compute_instance_group_manager.foobar", &manager), + "google_compute_instance_group_manager.igm-update", &manager), testAccCheckInstanceGroupManagerUpdated( - "google_compute_instance_group_manager.foobar", 3, - "google_compute_target_pool.foobaz", "terraform-test-foobaz"), + "google_compute_instance_group_manager.igm-update", 3, + "google_compute_target_pool.igm-update", "terraform-test-igm-update2"), ), }, }, @@ -152,8 +145,8 @@ func testAccCheckInstanceGroupManagerUpdated(n string, size int64, targetPool st } const testAccInstanceGroupManager_basic = ` -resource "google_compute_instance_template" "foobar" { - name = "terraform-test-foobar" +resource "google_compute_instance_template" "igm-basic" { + name = "terraform-test-igm-basic" machine_type = "n1-standard-1" can_ip_forward = false tags = ["foo", "bar"] @@ -177,25 +170,25 @@ resource "google_compute_instance_template" "foobar" { } } -resource "google_compute_target_pool" "foobar" { +resource "google_compute_target_pool" "igm-basic" { description = "Resource created for Terraform acceptance testing" - name = "terraform-test-foobar" + name = "terraform-test-igm-basic" session_affinity = "CLIENT_IP_PROTO" } -resource "google_compute_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "igm-basic" { description = "Terraform test instance group manager" - name = "terraform-test" - instance_template = "${google_compute_instance_template.foobar.self_link}" - target_pools = ["${google_compute_target_pool.foobar.self_link}"] - base_instance_name = "foobar" + name = "terraform-test-igm-basic" + instance_template = "${google_compute_instance_template.igm-basic.self_link}" + target_pools = ["${google_compute_target_pool.igm-basic.self_link}"] + base_instance_name = "igm-basic" zone = "us-central1-c" target_size = 2 }` const testAccInstanceGroupManager_update = ` -resource "google_compute_instance_template" "foobar" { - name = "terraform-test-foobar" +resource "google_compute_instance_template" "igm-update" { + name = "terraform-test-igm-update" machine_type = "n1-standard-1" can_ip_forward = false tags = ["foo", "bar"] @@ -219,56 +212,26 @@ resource "google_compute_instance_template" "foobar" { } } -resource "google_compute_instance_template" "foobaz" { - name = "terraform-test-foobaz" - machine_type = "n1-standard-1" - can_ip_forward = false - tags = ["foo", "bar"] - - disk { - source_image = "debian-cloud/debian-7-wheezy-v20140814" - auto_delete = true - boot = true - } - - network_interface { - network = "default" - } - - metadata { - foo = "bar" - } - - service_account { - scopes = ["userinfo-email", "compute-ro", "storage-ro"] - } -} - -resource "google_compute_target_pool" "foobar" { +resource "google_compute_target_pool" "igm-update" { description = "Resource created for Terraform acceptance testing" - name = "terraform-test-foobar" + name = "terraform-test-igm-update" session_affinity = "CLIENT_IP_PROTO" } -resource "google_compute_target_pool" "foobaz" { - description = "Resource created for Terraform acceptance testing" - name = "terraform-test-foobaz" - session_affinity = "CLIENT_IP_PROTO" -} - -resource "google_compute_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "igm-update" { description = "Terraform test instance group manager" - name = "terraform-test" - instance_template = "${google_compute_instance_template.foobar.self_link}" - target_pools = ["${google_compute_target_pool.foobaz.self_link}"] - base_instance_name = "foobar" + name = "terraform-test-igm-update" + instance_template = "${google_compute_instance_template.igm-update.self_link}" + target_pools = ["${google_compute_target_pool.igm-update.self_link}"] + base_instance_name = "igm-update" zone = "us-central1-c" target_size = 2 }` +// Change IGM's instance template and target size const testAccInstanceGroupManager_update2 = ` -resource "google_compute_instance_template" "foobar" { - name = "terraform-test-foobar" +resource "google_compute_instance_template" "igm-update" { + name = "terraform-test-igm-update" machine_type = "n1-standard-1" can_ip_forward = false tags = ["foo", "bar"] @@ -292,8 +255,14 @@ resource "google_compute_instance_template" "foobar" { } } -resource "google_compute_instance_template" "foobaz" { - name = "terraform-test-foobaz" +resource "google_compute_target_pool" "igm-update" { + description = "Resource created for Terraform acceptance testing" + name = "terraform-test-igm-update" + session_affinity = "CLIENT_IP_PROTO" +} + +resource "google_compute_instance_template" "igm-update2" { + name = "terraform-test-igm-update2" machine_type = "n1-standard-1" can_ip_forward = false tags = ["foo", "bar"] @@ -317,24 +286,13 @@ resource "google_compute_instance_template" "foobaz" { } } -resource "google_compute_target_pool" "foobar" { - description = "Resource created for Terraform acceptance testing" - name = "terraform-test-foobar" - session_affinity = "CLIENT_IP_PROTO" -} - -resource "google_compute_target_pool" "foobaz" { - description = "Resource created for Terraform acceptance testing" - name = "terraform-test-foobaz" - session_affinity = "CLIENT_IP_PROTO" -} - -resource "google_compute_instance_group_manager" "foobar" { +resource "google_compute_instance_group_manager" "igm-update" { description = "Terraform test instance group manager" - name = "terraform-test" - instance_template = "${google_compute_instance_template.foobaz.self_link}" - target_pools = ["${google_compute_target_pool.foobaz.self_link}"] - base_instance_name = "foobar" + name = "terraform-test-igm-update" + instance_template = "${google_compute_instance_template.igm-update2.self_link}" + target_pools = ["${google_compute_target_pool.igm-update.self_link}"] + base_instance_name = "igm-update" zone = "us-central1-c" target_size = 3 }` + From e8e54954832f556099d3196403401799828990b1 Mon Sep 17 00:00:00 2001 From: Dave Cunningham Date: Tue, 28 Jul 2015 14:09:43 -0400 Subject: [PATCH 50/73] Increase timeout, IGM delete can be slow --- .../providers/google/resource_compute_instance_group_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/google/resource_compute_instance_group_manager.go b/builtin/providers/google/resource_compute_instance_group_manager.go index a07f010e0..ca0967e37 100644 --- a/builtin/providers/google/resource_compute_instance_group_manager.go +++ b/builtin/providers/google/resource_compute_instance_group_manager.go @@ -93,7 +93,7 @@ func waitOpZone(config *Config, op *compute.Operation, zone string, Type: OperationWaitZone, } state := w.Conf() - state.Timeout = 2 * time.Minute + state.Timeout = 8 * time.Minute state.MinTimeout = 1 * time.Second opRaw, err := state.WaitForState() if err != nil { From 8527174c6ea8496654e03faa8598f2d422afbd36 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Tue, 28 Jul 2015 14:02:26 -0500 Subject: [PATCH 51/73] provider/aws: Fix issue with IAM Server Certificates and Chains --- .../aws/resource_aws_iam_server_certificate.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/builtin/providers/aws/resource_aws_iam_server_certificate.go b/builtin/providers/aws/resource_aws_iam_server_certificate.go index ac1496133..cea03b2be 100644 --- a/builtin/providers/aws/resource_aws_iam_server_certificate.go +++ b/builtin/providers/aws/resource_aws_iam_server_certificate.go @@ -4,6 +4,7 @@ import ( "crypto/sha1" "encoding/hex" "fmt" + "log" "strings" "github.com/aws/aws-sdk-go/aws" @@ -34,8 +35,9 @@ func resourceAwsIAMServerCertificate() *schema.Resource { }, "path": &schema.Schema{ - Type: schema.TypeBool, + Type: schema.TypeString, Optional: true, + Default: "/", ForceNew: true, }, @@ -74,10 +76,11 @@ func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interfac createOpts.CertificateChain = aws.String(v.(string)) } - if v, ok := d.GetOk("Path"); ok { + if v, ok := d.GetOk("path"); ok { createOpts.Path = aws.String(v.(string)) } + log.Printf("[DEBUG] Creating IAM Server Certificate with opts: %s", createOpts) resp, err := conn.UploadServerCertificate(createOpts) if err != nil { if awsErr, ok := err.(awserr.Error); ok { @@ -107,7 +110,12 @@ func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{ // these values should always be present, and have a default if not set in // configuration, and so safe to reference with nil checks d.Set("certificate_body", normalizeCert(resp.ServerCertificate.CertificateBody)) - d.Set("certificate_chain", normalizeCert(resp.ServerCertificate.CertificateChain)) + + c := normalizeCert(resp.ServerCertificate.CertificateChain) + if c != "" { + d.Set("certificate_chain", c) + } + d.Set("path", resp.ServerCertificate.ServerCertificateMetadata.Path) d.Set("arn", resp.ServerCertificate.ServerCertificateMetadata.ARN) @@ -132,9 +140,10 @@ func resourceAwsIAMServerCertificateDelete(d *schema.ResourceData, meta interfac } func normalizeCert(cert interface{}) string { - if cert == nil { + if cert == nil || cert == (*string)(nil) { return "" } + switch cert.(type) { case string: hash := sha1.Sum([]byte(strings.TrimSpace(cert.(string)))) From 8031d60ced4b98690396ae71e4692ebdbb550c6d Mon Sep 17 00:00:00 2001 From: Dave Cunningham Date: Tue, 28 Jul 2015 16:01:04 -0400 Subject: [PATCH 52/73] Update CHANGELOG. --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4869e2e0a..a6720b41d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## 0.6.2 (Unreleased) +FEATURES: + + * **New resource: `google_compute_instance_group_manager`** [GH-2868] + * **New resource: `google_compute_autoscaler`** [GH-2868] + IMPROVEMENTS: * core: Add resource IDs to errors coming from `apply`/`refresh` [GH-2815] From 579ccbefea4ae52bfbccb6e643481e0b5ceb4230 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Tue, 28 Jul 2015 15:29:46 -0500 Subject: [PATCH 53/73] provider/aws: Update source to comply with upstream breaking change --- builtin/providers/aws/autoscaling_tags.go | 2 +- builtin/providers/aws/config.go | 8 ++-- builtin/providers/aws/network_acl_entry.go | 12 ++--- .../providers/aws/network_acl_entry_test.go | 36 +++++++-------- ...source_aws_app_cookie_stickiness_policy.go | 4 +- .../aws/resource_aws_autoscaling_group.go | 30 ++++++------- .../resource_aws_autoscaling_group_test.go | 2 +- .../aws/resource_aws_autoscaling_policy.go | 6 +-- .../resource_aws_cloudwatch_metric_alarm.go | 8 ++-- .../aws/resource_aws_customer_gateway.go | 2 +- .../providers/aws/resource_aws_db_instance.go | 44 +++++++++---------- .../aws/resource_aws_dynamodb_table.go | 16 +++---- .../providers/aws/resource_aws_ebs_volume.go | 6 +-- .../providers/aws/resource_aws_ecs_cluster.go | 5 +-- .../providers/aws/resource_aws_ecs_service.go | 17 ++++--- .../aws/resource_aws_ecs_task_definition.go | 5 +-- .../aws/resource_aws_elasticache_cluster.go | 17 ++++--- ...esource_aws_elasticache_parameter_group.go | 4 +- builtin/providers/aws/resource_aws_elb.go | 18 ++++---- .../providers/aws/resource_aws_elb_test.go | 12 ++--- .../providers/aws/resource_aws_flow_log.go | 3 +- .../providers/aws/resource_aws_iam_policy.go | 2 +- .../providers/aws/resource_aws_instance.go | 41 +++++++++-------- .../aws/resource_aws_instance_test.go | 7 ++- .../aws/resource_aws_kinesis_stream.go | 6 +-- .../aws/resource_aws_kinesis_stream_test.go | 4 +- .../aws/resource_aws_lambda_function.go | 4 +- .../aws/resource_aws_launch_configuration.go | 18 ++++---- ...esource_aws_lb_cookie_stickiness_policy.go | 6 +-- .../aws/resource_aws_network_interface.go | 6 +-- .../aws/resource_aws_route53_health_check.go | 10 ++--- .../aws/resource_aws_route53_record.go | 6 +-- .../aws/resource_aws_security_group.go | 4 +- .../aws/resource_aws_security_group_rule.go | 9 ++-- ...esource_aws_security_group_rule_migrate.go | 4 +- .../resource_aws_security_group_rule_test.go | 23 +++++----- .../aws/resource_aws_security_group_test.go | 12 ++--- .../aws/resource_aws_spot_instance_request.go | 9 ++-- builtin/providers/aws/resource_aws_subnet.go | 2 +- .../aws/resource_aws_volume_attachment.go | 2 +- .../aws/resource_aws_vpn_connection.go | 2 +- builtin/providers/aws/structure.go | 8 ++-- builtin/providers/aws/structure_test.go | 34 +++++++------- builtin/providers/aws/tags.go | 3 +- state/remote/s3.go | 2 +- state/remote/s3_test.go | 2 +- 46 files changed, 236 insertions(+), 247 deletions(-) diff --git a/builtin/providers/aws/autoscaling_tags.go b/builtin/providers/aws/autoscaling_tags.go index 9a41a3291..7f5b071f5 100644 --- a/builtin/providers/aws/autoscaling_tags.go +++ b/builtin/providers/aws/autoscaling_tags.go @@ -122,7 +122,7 @@ func autoscalingTagsFromMap(m map[string]interface{}, resourceID string) []*auto result = append(result, &autoscaling.Tag{ Key: aws.String(k), Value: aws.String(attr["value"].(string)), - PropagateAtLaunch: aws.Boolean(attr["propagate_at_launch"].(bool)), + PropagateAtLaunch: aws.Bool(attr["propagate_at_launch"].(bool)), ResourceID: aws.String(resourceID), ResourceType: aws.String("auto-scaling-group"), }) diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index f58938285..6985f5585 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -82,8 +82,8 @@ func (c *Config) Client() (interface{}, error) { creds := credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token) awsConfig := &aws.Config{ Credentials: creds, - Region: c.Region, - MaxRetries: c.MaxRetries, + Region: aws.String(c.Region), + MaxRetries: aws.Int(c.MaxRetries), } log.Println("[INFO] Initializing IAM Connection") @@ -135,8 +135,8 @@ func (c *Config) Client() (interface{}, error) { log.Println("[INFO] Initializing Route 53 connection") client.r53conn = route53.New(&aws.Config{ Credentials: creds, - Region: "us-east-1", - MaxRetries: c.MaxRetries, + Region: aws.String("us-east-1"), + MaxRetries: aws.Int(c.MaxRetries), }) log.Println("[INFO] Initializing Elasticache Connection") diff --git a/builtin/providers/aws/network_acl_entry.go b/builtin/providers/aws/network_acl_entry.go index 908bc885a..00ca77624 100644 --- a/builtin/providers/aws/network_acl_entry.go +++ b/builtin/providers/aws/network_acl_entry.go @@ -26,12 +26,12 @@ func expandNetworkAclEntries(configured []interface{}, entryType string) ([]*ec2 e := &ec2.NetworkACLEntry{ Protocol: aws.String(strconv.Itoa(p)), PortRange: &ec2.PortRange{ - From: aws.Long(int64(data["from_port"].(int))), - To: aws.Long(int64(data["to_port"].(int))), + From: aws.Int64(int64(data["from_port"].(int))), + To: aws.Int64(int64(data["to_port"].(int))), }, - Egress: aws.Boolean((entryType == "egress")), + Egress: aws.Bool((entryType == "egress")), RuleAction: aws.String(data["action"].(string)), - RuleNumber: aws.Long(int64(data["rule_no"].(int))), + RuleNumber: aws.Int64(int64(data["rule_no"].(int))), CIDRBlock: aws.String(data["cidr_block"].(string)), } @@ -39,10 +39,10 @@ func expandNetworkAclEntries(configured []interface{}, entryType string) ([]*ec2 if p == 1 { e.ICMPTypeCode = &ec2.ICMPTypeCode{} if v, ok := data["icmp_code"]; ok { - e.ICMPTypeCode.Code = aws.Long(int64(v.(int))) + e.ICMPTypeCode.Code = aws.Int64(int64(v.(int))) } if v, ok := data["icmp_type"]; ok { - e.ICMPTypeCode.Type = aws.Long(int64(v.(int))) + e.ICMPTypeCode.Type = aws.Int64(int64(v.(int))) } } diff --git a/builtin/providers/aws/network_acl_entry_test.go b/builtin/providers/aws/network_acl_entry_test.go index c34b7dfc3..aa7288c10 100644 --- a/builtin/providers/aws/network_acl_entry_test.go +++ b/builtin/providers/aws/network_acl_entry_test.go @@ -41,35 +41,35 @@ func Test_expandNetworkACLEntry(t *testing.T) { &ec2.NetworkACLEntry{ Protocol: aws.String("6"), PortRange: &ec2.PortRange{ - From: aws.Long(22), - To: aws.Long(22), + From: aws.Int64(22), + To: aws.Int64(22), }, RuleAction: aws.String("deny"), - RuleNumber: aws.Long(1), + RuleNumber: aws.Int64(1), CIDRBlock: aws.String("0.0.0.0/0"), - Egress: aws.Boolean(true), + Egress: aws.Bool(true), }, &ec2.NetworkACLEntry{ Protocol: aws.String("6"), PortRange: &ec2.PortRange{ - From: aws.Long(443), - To: aws.Long(443), + From: aws.Int64(443), + To: aws.Int64(443), }, RuleAction: aws.String("deny"), - RuleNumber: aws.Long(2), + RuleNumber: aws.Int64(2), CIDRBlock: aws.String("0.0.0.0/0"), - Egress: aws.Boolean(true), + Egress: aws.Bool(true), }, &ec2.NetworkACLEntry{ Protocol: aws.String("-1"), PortRange: &ec2.PortRange{ - From: aws.Long(443), - To: aws.Long(443), + From: aws.Int64(443), + To: aws.Int64(443), }, RuleAction: aws.String("deny"), - RuleNumber: aws.Long(2), + RuleNumber: aws.Int64(2), CIDRBlock: aws.String("0.0.0.0/0"), - Egress: aws.Boolean(true), + Egress: aws.Bool(true), }, } @@ -88,21 +88,21 @@ func Test_flattenNetworkACLEntry(t *testing.T) { &ec2.NetworkACLEntry{ Protocol: aws.String("tcp"), PortRange: &ec2.PortRange{ - From: aws.Long(22), - To: aws.Long(22), + From: aws.Int64(22), + To: aws.Int64(22), }, RuleAction: aws.String("deny"), - RuleNumber: aws.Long(1), + RuleNumber: aws.Int64(1), CIDRBlock: aws.String("0.0.0.0/0"), }, &ec2.NetworkACLEntry{ Protocol: aws.String("tcp"), PortRange: &ec2.PortRange{ - From: aws.Long(443), - To: aws.Long(443), + From: aws.Int64(443), + To: aws.Int64(443), }, RuleAction: aws.String("deny"), - RuleNumber: aws.Long(2), + RuleNumber: aws.Int64(2), CIDRBlock: aws.String("0.0.0.0/0"), }, } diff --git a/builtin/providers/aws/resource_aws_app_cookie_stickiness_policy.go b/builtin/providers/aws/resource_aws_app_cookie_stickiness_policy.go index ca459ead7..3f7e1bf7f 100644 --- a/builtin/providers/aws/resource_aws_app_cookie_stickiness_policy.go +++ b/builtin/providers/aws/resource_aws_app_cookie_stickiness_policy.go @@ -64,7 +64,7 @@ func resourceAwsAppCookieStickinessPolicyCreate(d *schema.ResourceData, meta int setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ LoadBalancerName: aws.String(d.Get("load_balancer").(string)), - LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))), + LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))), PolicyNames: []*string{aws.String(d.Get("name").(string))}, } @@ -129,7 +129,7 @@ func resourceAwsAppCookieStickinessPolicyDelete(d *schema.ResourceData, meta int // policy itself. setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ LoadBalancerName: aws.String(d.Get("load_balancer").(string)), - LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))), + LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))), PolicyNames: []*string{}, } diff --git a/builtin/providers/aws/resource_aws_autoscaling_group.go b/builtin/providers/aws/resource_aws_autoscaling_group.go index ae6c94b33..88fa2561d 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group.go @@ -131,8 +131,8 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{}) var autoScalingGroupOpts autoscaling.CreateAutoScalingGroupInput autoScalingGroupOpts.AutoScalingGroupName = aws.String(d.Get("name").(string)) autoScalingGroupOpts.LaunchConfigurationName = aws.String(d.Get("launch_configuration").(string)) - autoScalingGroupOpts.MinSize = aws.Long(int64(d.Get("min_size").(int))) - autoScalingGroupOpts.MaxSize = aws.Long(int64(d.Get("max_size").(int))) + autoScalingGroupOpts.MinSize = aws.Int64(int64(d.Get("min_size").(int))) + autoScalingGroupOpts.MaxSize = aws.Int64(int64(d.Get("max_size").(int))) // Availability Zones are optional if VPC Zone Identifer(s) are specified if v, ok := d.GetOk("availability_zones"); ok && v.(*schema.Set).Len() > 0 { @@ -145,7 +145,7 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{}) } if v, ok := d.GetOk("default_cooldown"); ok { - autoScalingGroupOpts.DefaultCooldown = aws.Long(int64(v.(int))) + autoScalingGroupOpts.DefaultCooldown = aws.Int64(int64(v.(int))) } if v, ok := d.GetOk("health_check_type"); ok && v.(string) != "" { @@ -153,11 +153,11 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{}) } if v, ok := d.GetOk("desired_capacity"); ok { - autoScalingGroupOpts.DesiredCapacity = aws.Long(int64(v.(int))) + autoScalingGroupOpts.DesiredCapacity = aws.Int64(int64(v.(int))) } if v, ok := d.GetOk("health_check_grace_period"); ok { - autoScalingGroupOpts.HealthCheckGracePeriod = aws.Long(int64(v.(int))) + autoScalingGroupOpts.HealthCheckGracePeriod = aws.Int64(int64(v.(int))) } if v, ok := d.GetOk("load_balancers"); ok && v.(*schema.Set).Len() > 0 { @@ -224,11 +224,11 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) } if d.HasChange("default_cooldown") { - opts.DefaultCooldown = aws.Long(int64(d.Get("default_cooldown").(int))) + opts.DefaultCooldown = aws.Int64(int64(d.Get("default_cooldown").(int))) } if d.HasChange("desired_capacity") { - opts.DesiredCapacity = aws.Long(int64(d.Get("desired_capacity").(int))) + opts.DesiredCapacity = aws.Int64(int64(d.Get("desired_capacity").(int))) } if d.HasChange("launch_configuration") { @@ -236,19 +236,19 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) } if d.HasChange("min_size") { - opts.MinSize = aws.Long(int64(d.Get("min_size").(int))) + opts.MinSize = aws.Int64(int64(d.Get("min_size").(int))) } if d.HasChange("max_size") { - opts.MaxSize = aws.Long(int64(d.Get("max_size").(int))) + opts.MaxSize = aws.Int64(int64(d.Get("max_size").(int))) } if d.HasChange("health_check_grace_period") { - opts.HealthCheckGracePeriod = aws.Long(int64(d.Get("health_check_grace_period").(int))) + opts.HealthCheckGracePeriod = aws.Int64(int64(d.Get("health_check_grace_period").(int))) } if d.HasChange("health_check_type") { - opts.HealthCheckGracePeriod = aws.Long(int64(d.Get("health_check_grace_period").(int))) + opts.HealthCheckGracePeriod = aws.Int64(int64(d.Get("health_check_grace_period").(int))) opts.HealthCheckType = aws.String(d.Get("health_check_type").(string)) } @@ -342,7 +342,7 @@ func resourceAwsAutoscalingGroupDelete(d *schema.ResourceData, meta interface{}) // and then delete the group. This bypasses that and leaves // resources potentially dangling. if d.Get("force_delete").(bool) { - deleteopts.ForceDelete = aws.Boolean(true) + deleteopts.ForceDelete = aws.Bool(true) } // We retry the delete operation to handle InUse/InProgress errors coming @@ -418,9 +418,9 @@ func resourceAwsAutoscalingGroupDrain(d *schema.ResourceData, meta interface{}) log.Printf("[DEBUG] Reducing autoscaling group capacity to zero") opts := autoscaling.UpdateAutoScalingGroupInput{ AutoScalingGroupName: aws.String(d.Id()), - DesiredCapacity: aws.Long(0), - MinSize: aws.Long(0), - MaxSize: aws.Long(0), + DesiredCapacity: aws.Int64(0), + MinSize: aws.Int64(0), + MaxSize: aws.Int64(0), } if _, err := conn.UpdateAutoScalingGroup(&opts); err != nil { return fmt.Errorf("Error setting capacity to zero to drain: %s", err) diff --git a/builtin/providers/aws/resource_aws_autoscaling_group_test.go b/builtin/providers/aws/resource_aws_autoscaling_group_test.go index 9f26bb7f2..814a51bc7 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_group_test.go +++ b/builtin/providers/aws/resource_aws_autoscaling_group_test.go @@ -217,7 +217,7 @@ func testAccCheckAWSAutoScalingGroupAttributes(group *autoscaling.Group) resourc t := &autoscaling.TagDescription{ Key: aws.String("Foo"), Value: aws.String("foo-bar"), - PropagateAtLaunch: aws.Boolean(true), + PropagateAtLaunch: aws.Bool(true), ResourceType: aws.String("auto-scaling-group"), ResourceID: group.AutoScalingGroupName, } diff --git a/builtin/providers/aws/resource_aws_autoscaling_policy.go b/builtin/providers/aws/resource_aws_autoscaling_policy.go index d2f6d2d47..07e94feb8 100644 --- a/builtin/providers/aws/resource_aws_autoscaling_policy.go +++ b/builtin/providers/aws/resource_aws_autoscaling_policy.go @@ -140,15 +140,15 @@ func getAwsAutoscalingPutScalingPolicyInput(d *schema.ResourceData) autoscaling. } if v, ok := d.GetOk("cooldown"); ok { - params.Cooldown = aws.Long(int64(v.(int))) + params.Cooldown = aws.Int64(int64(v.(int))) } if v, ok := d.GetOk("scaling_adjustment"); ok { - params.ScalingAdjustment = aws.Long(int64(v.(int))) + params.ScalingAdjustment = aws.Int64(int64(v.(int))) } if v, ok := d.GetOk("min_adjustment_step"); ok { - params.MinAdjustmentStep = aws.Long(int64(v.(int))) + params.MinAdjustmentStep = aws.Int64(int64(v.(int))) } return params diff --git a/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go b/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go index 4c8b40140..2594061dd 100644 --- a/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go +++ b/builtin/providers/aws/resource_aws_cloudwatch_metric_alarm.go @@ -197,16 +197,16 @@ func getAwsCloudWatchPutMetricAlarmInput(d *schema.ResourceData) cloudwatch.PutM params := cloudwatch.PutMetricAlarmInput{ AlarmName: aws.String(d.Get("alarm_name").(string)), ComparisonOperator: aws.String(d.Get("comparison_operator").(string)), - EvaluationPeriods: aws.Long(int64(d.Get("evaluation_periods").(int))), + EvaluationPeriods: aws.Int64(int64(d.Get("evaluation_periods").(int))), MetricName: aws.String(d.Get("metric_name").(string)), Namespace: aws.String(d.Get("namespace").(string)), - Period: aws.Long(int64(d.Get("period").(int))), + Period: aws.Int64(int64(d.Get("period").(int))), Statistic: aws.String(d.Get("statistic").(string)), - Threshold: aws.Double(d.Get("threshold").(float64)), + Threshold: aws.Float64(d.Get("threshold").(float64)), } if v := d.Get("actions_enabled"); v != nil { - params.ActionsEnabled = aws.Boolean(v.(bool)) + params.ActionsEnabled = aws.Bool(v.(bool)) } if v, ok := d.GetOk("alarm_description"); ok { diff --git a/builtin/providers/aws/resource_aws_customer_gateway.go b/builtin/providers/aws/resource_aws_customer_gateway.go index fa4322304..3c7469efc 100644 --- a/builtin/providers/aws/resource_aws_customer_gateway.go +++ b/builtin/providers/aws/resource_aws_customer_gateway.go @@ -48,7 +48,7 @@ func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{}) conn := meta.(*AWSClient).ec2conn createOpts := &ec2.CreateCustomerGatewayInput{ - BGPASN: aws.Long(int64(d.Get("bgp_asn").(int))), + BGPASN: aws.Int64(int64(d.Get("bgp_asn").(int))), PublicIP: aws.String(d.Get("ip_address").(string)), Type: aws.String(d.Get("type").(string)), } diff --git a/builtin/providers/aws/resource_aws_db_instance.go b/builtin/providers/aws/resource_aws_db_instance.go index 6ca1916b5..78c6a0acd 100644 --- a/builtin/providers/aws/resource_aws_db_instance.go +++ b/builtin/providers/aws/resource_aws_db_instance.go @@ -272,11 +272,11 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error Tags: tags, } if attr, ok := d.GetOk("iops"); ok { - opts.IOPS = aws.Long(int64(attr.(int))) + opts.IOPS = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("port"); ok { - opts.Port = aws.Long(int64(attr.(int))) + opts.Port = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("availability_zone"); ok { @@ -284,7 +284,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr, ok := d.GetOk("publicly_accessible"); ok { - opts.PubliclyAccessible = aws.Boolean(attr.(bool)) + opts.PubliclyAccessible = aws.Bool(attr.(bool)) } _, err := conn.CreateDBInstanceReadReplica(&opts) if err != nil { @@ -299,7 +299,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr, ok := d.GetOk("auto_minor_version_upgrade"); ok { - opts.AutoMinorVersionUpgrade = aws.Boolean(attr.(bool)) + opts.AutoMinorVersionUpgrade = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("availability_zone"); ok { @@ -315,7 +315,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr, ok := d.GetOk("iops"); ok { - opts.IOPS = aws.Long(int64(attr.(int))) + opts.IOPS = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("license_model"); ok { @@ -323,7 +323,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr, ok := d.GetOk("multi_az"); ok { - opts.MultiAZ = aws.Boolean(attr.(bool)) + opts.MultiAZ = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("option_group_name"); ok { @@ -331,11 +331,11 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr, ok := d.GetOk("port"); ok { - opts.Port = aws.Long(int64(attr.(int))) + opts.Port = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("publicly_accessible"); ok { - opts.PubliclyAccessible = aws.Boolean(attr.(bool)) + opts.PubliclyAccessible = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("tde_credential_arn"); ok { @@ -352,7 +352,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } } else { opts := rds.CreateDBInstanceInput{ - AllocatedStorage: aws.Long(int64(d.Get("allocated_storage").(int))), + AllocatedStorage: aws.Int64(int64(d.Get("allocated_storage").(int))), DBName: aws.String(d.Get("name").(string)), DBInstanceClass: aws.String(d.Get("instance_class").(string)), DBInstanceIdentifier: aws.String(d.Get("identifier").(string)), @@ -360,14 +360,14 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error MasterUserPassword: aws.String(d.Get("password").(string)), Engine: aws.String(d.Get("engine").(string)), EngineVersion: aws.String(d.Get("engine_version").(string)), - StorageEncrypted: aws.Boolean(d.Get("storage_encrypted").(bool)), + StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)), Tags: tags, } attr := d.Get("backup_retention_period") - opts.BackupRetentionPeriod = aws.Long(int64(attr.(int))) + opts.BackupRetentionPeriod = aws.Int64(int64(attr.(int))) if attr, ok := d.GetOk("multi_az"); ok { - opts.MultiAZ = aws.Boolean(attr.(bool)) + opts.MultiAZ = aws.Bool(attr.(bool)) } if attr, ok := d.GetOk("maintenance_window"); ok { @@ -409,11 +409,11 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr, ok := d.GetOk("iops"); ok { - opts.IOPS = aws.Long(int64(attr.(int))) + opts.IOPS = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("port"); ok { - opts.Port = aws.Long(int64(attr.(int))) + opts.Port = aws.Int64(int64(attr.(int))) } if attr, ok := d.GetOk("availability_zone"); ok { @@ -421,7 +421,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error } if attr, ok := d.GetOk("publicly_accessible"); ok { - opts.PubliclyAccessible = aws.Boolean(attr.(bool)) + opts.PubliclyAccessible = aws.Bool(attr.(bool)) } log.Printf("[DEBUG] DB Instance create configuration: %#v", opts) @@ -571,7 +571,7 @@ func resourceAwsDbInstanceDelete(d *schema.ResourceData, meta interface{}) error finalSnapshot := d.Get("final_snapshot_identifier").(string) if finalSnapshot == "" { - opts.SkipFinalSnapshot = aws.Boolean(true) + opts.SkipFinalSnapshot = aws.Bool(true) } else { opts.FinalDBSnapshotIdentifier = aws.String(finalSnapshot) } @@ -605,7 +605,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error d.Partial(true) req := &rds.ModifyDBInstanceInput{ - ApplyImmediately: aws.Boolean(d.Get("apply_immediately").(bool)), + ApplyImmediately: aws.Bool(d.Get("apply_immediately").(bool)), DBInstanceIdentifier: aws.String(d.Id()), } d.SetPartial("apply_immediately") @@ -613,12 +613,12 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error requestUpdate := false if d.HasChange("allocated_storage") { d.SetPartial("allocated_storage") - req.AllocatedStorage = aws.Long(int64(d.Get("allocated_storage").(int))) + req.AllocatedStorage = aws.Int64(int64(d.Get("allocated_storage").(int))) requestUpdate = true } if d.HasChange("backup_retention_period") { d.SetPartial("backup_retention_period") - req.BackupRetentionPeriod = aws.Long(int64(d.Get("backup_retention_period").(int))) + req.BackupRetentionPeriod = aws.Int64(int64(d.Get("backup_retention_period").(int))) requestUpdate = true } if d.HasChange("instance_class") { @@ -638,7 +638,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("iops") { d.SetPartial("iops") - req.IOPS = aws.Long(int64(d.Get("iops").(int))) + req.IOPS = aws.Int64(int64(d.Get("iops").(int))) requestUpdate = true } if d.HasChange("backup_window") { @@ -658,7 +658,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("multi_az") { d.SetPartial("multi_az") - req.MultiAZ = aws.Boolean(d.Get("multi_az").(bool)) + req.MultiAZ = aws.Bool(d.Get("multi_az").(bool)) requestUpdate = true } if d.HasChange("storage_type") { @@ -706,7 +706,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error DBInstanceIdentifier: aws.String(d.Id()), } attr := d.Get("backup_retention_period") - opts.BackupRetentionPeriod = aws.Long(int64(attr.(int))) + opts.BackupRetentionPeriod = aws.Int64(int64(attr.(int))) if attr, ok := d.GetOk("backup_window"); ok { opts.PreferredBackupWindow = aws.String(attr.(string)) } diff --git a/builtin/providers/aws/resource_aws_dynamodb_table.go b/builtin/providers/aws/resource_aws_dynamodb_table.go index 9a860768e..cfa9e49f8 100644 --- a/builtin/providers/aws/resource_aws_dynamodb_table.go +++ b/builtin/providers/aws/resource_aws_dynamodb_table.go @@ -166,8 +166,8 @@ func resourceAwsDynamoDbTableCreate(d *schema.ResourceData, meta interface{}) er log.Printf("[DEBUG] DynamoDB table create: %s", name) throughput := &dynamodb.ProvisionedThroughput{ - ReadCapacityUnits: aws.Long(int64(d.Get("read_capacity").(int))), - WriteCapacityUnits: aws.Long(int64(d.Get("write_capacity").(int))), + ReadCapacityUnits: aws.Int64(int64(d.Get("read_capacity").(int))), + WriteCapacityUnits: aws.Int64(int64(d.Get("write_capacity").(int))), } hash_key_name := d.Get("hash_key").(string) @@ -318,8 +318,8 @@ func resourceAwsDynamoDbTableUpdate(d *schema.ResourceData, meta interface{}) er } throughput := &dynamodb.ProvisionedThroughput{ - ReadCapacityUnits: aws.Long(int64(d.Get("read_capacity").(int))), - WriteCapacityUnits: aws.Long(int64(d.Get("write_capacity").(int))), + ReadCapacityUnits: aws.Int64(int64(d.Get("read_capacity").(int))), + WriteCapacityUnits: aws.Int64(int64(d.Get("write_capacity").(int))), } req.ProvisionedThroughput = throughput @@ -486,8 +486,8 @@ func resourceAwsDynamoDbTableUpdate(d *schema.ResourceData, meta interface{}) er Update: &dynamodb.UpdateGlobalSecondaryIndexAction{ IndexName: aws.String(gsidata["name"].(string)), ProvisionedThroughput: &dynamodb.ProvisionedThroughput{ - WriteCapacityUnits: aws.Long(int64(gsiWriteCapacity)), - ReadCapacityUnits: aws.Long(int64(gsiReadCapacity)), + WriteCapacityUnits: aws.Int64(int64(gsiWriteCapacity)), + ReadCapacityUnits: aws.Int64(int64(gsiReadCapacity)), }, }, } @@ -634,8 +634,8 @@ func createGSIFromData(data *map[string]interface{}) dynamodb.GlobalSecondaryInd KeySchema: key_schema, Projection: projection, ProvisionedThroughput: &dynamodb.ProvisionedThroughput{ - WriteCapacityUnits: aws.Long(int64(writeCapacity)), - ReadCapacityUnits: aws.Long(int64(readCapacity)), + WriteCapacityUnits: aws.Int64(int64(writeCapacity)), + ReadCapacityUnits: aws.Int64(int64(readCapacity)), }, } } diff --git a/builtin/providers/aws/resource_aws_ebs_volume.go b/builtin/providers/aws/resource_aws_ebs_volume.go index d225f26ce..fd35aebc0 100644 --- a/builtin/providers/aws/resource_aws_ebs_volume.go +++ b/builtin/providers/aws/resource_aws_ebs_volume.go @@ -74,16 +74,16 @@ func resourceAwsEbsVolumeCreate(d *schema.ResourceData, meta interface{}) error AvailabilityZone: aws.String(d.Get("availability_zone").(string)), } if value, ok := d.GetOk("encrypted"); ok { - request.Encrypted = aws.Boolean(value.(bool)) + request.Encrypted = aws.Bool(value.(bool)) } if value, ok := d.GetOk("iops"); ok { - request.IOPS = aws.Long(int64(value.(int))) + request.IOPS = aws.Int64(int64(value.(int))) } if value, ok := d.GetOk("kms_key_id"); ok { request.KMSKeyID = aws.String(value.(string)) } if value, ok := d.GetOk("size"); ok { - request.Size = aws.Long(int64(value.(int))) + request.Size = aws.Int64(int64(value.(int))) } if value, ok := d.GetOk("snapshot_id"); ok { request.SnapshotID = aws.String(value.(string)) diff --git a/builtin/providers/aws/resource_aws_ecs_cluster.go b/builtin/providers/aws/resource_aws_ecs_cluster.go index f9ad036a2..0f692a0e4 100644 --- a/builtin/providers/aws/resource_aws_ecs_cluster.go +++ b/builtin/providers/aws/resource_aws_ecs_cluster.go @@ -6,7 +6,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ecs" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -58,7 +57,7 @@ func resourceAwsEcsClusterRead(d *schema.ResourceData, meta interface{}) error { if err != nil { return err } - log.Printf("[DEBUG] Received ECS clusters: %s", awsutil.StringValue(out.Clusters)) + log.Printf("[DEBUG] Received ECS clusters: %s", out.Clusters) d.SetId(*out.Clusters[0].ClusterARN) d.Set("name", *out.Clusters[0].ClusterName) @@ -77,7 +76,7 @@ func resourceAwsEcsClusterDelete(d *schema.ResourceData, meta interface{}) error }) if err == nil { - log.Printf("[DEBUG] ECS cluster %s deleted: %s", d.Id(), awsutil.StringValue(out)) + log.Printf("[DEBUG] ECS cluster %s deleted: %s", d.Id(), out) return nil } diff --git a/builtin/providers/aws/resource_aws_ecs_service.go b/builtin/providers/aws/resource_aws_ecs_service.go index a92a761f9..41c54d878 100644 --- a/builtin/providers/aws/resource_aws_ecs_service.go +++ b/builtin/providers/aws/resource_aws_ecs_service.go @@ -9,7 +9,6 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ecs" "github.com/aws/aws-sdk-go/service/iam" "github.com/hashicorp/terraform/helper/hashcode" @@ -88,7 +87,7 @@ func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error input := ecs.CreateServiceInput{ ServiceName: aws.String(d.Get("name").(string)), TaskDefinition: aws.String(d.Get("task_definition").(string)), - DesiredCount: aws.Long(int64(d.Get("desired_count").(int))), + DesiredCount: aws.Int64(int64(d.Get("desired_count").(int))), ClientToken: aws.String(resource.UniqueId()), } @@ -98,14 +97,14 @@ func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error loadBalancers := expandEcsLoadBalancers(d.Get("load_balancer").(*schema.Set).List()) if len(loadBalancers) > 0 { - log.Printf("[DEBUG] Adding ECS load balancers: %s", awsutil.StringValue(loadBalancers)) + log.Printf("[DEBUG] Adding ECS load balancers: %s", loadBalancers) input.LoadBalancers = loadBalancers } if v, ok := d.GetOk("iam_role"); ok { input.Role = aws.String(v.(string)) } - log.Printf("[DEBUG] Creating ECS service: %s", awsutil.StringValue(input)) + log.Printf("[DEBUG] Creating ECS service: %s", input) out, err := conn.CreateService(&input) if err != nil { return err @@ -139,7 +138,7 @@ func resourceAwsEcsServiceRead(d *schema.ResourceData, meta interface{}) error { } service := out.Services[0] - log.Printf("[DEBUG] Received ECS service %s", awsutil.StringValue(service)) + log.Printf("[DEBUG] Received ECS service %s", service) d.SetId(*service.ServiceARN) d.Set("name", *service.ServiceName) @@ -177,7 +176,7 @@ func resourceAwsEcsServiceUpdate(d *schema.ResourceData, meta interface{}) error if d.HasChange("desired_count") { _, n := d.GetChange("desired_count") - input.DesiredCount = aws.Long(int64(n.(int))) + input.DesiredCount = aws.Int64(int64(n.(int))) } if d.HasChange("task_definition") { _, n := d.GetChange("task_definition") @@ -189,7 +188,7 @@ func resourceAwsEcsServiceUpdate(d *schema.ResourceData, meta interface{}) error return err } service := out.Service - log.Printf("[DEBUG] Updated ECS service %s", awsutil.StringValue(service)) + log.Printf("[DEBUG] Updated ECS service %s", service) return resourceAwsEcsServiceRead(d, meta) } @@ -217,7 +216,7 @@ func resourceAwsEcsServiceDelete(d *schema.ResourceData, meta interface{}) error _, err = conn.UpdateService(&ecs.UpdateServiceInput{ Service: aws.String(d.Id()), Cluster: aws.String(d.Get("cluster").(string)), - DesiredCount: aws.Long(int64(0)), + DesiredCount: aws.Int64(int64(0)), }) if err != nil { return err @@ -229,7 +228,7 @@ func resourceAwsEcsServiceDelete(d *schema.ResourceData, meta interface{}) error Cluster: aws.String(d.Get("cluster").(string)), } - log.Printf("[DEBUG] Deleting ECS service %s", awsutil.StringValue(input)) + log.Printf("[DEBUG] Deleting ECS service %s", input) out, err := conn.DeleteService(&input) if err != nil { return err diff --git a/builtin/providers/aws/resource_aws_ecs_task_definition.go b/builtin/providers/aws/resource_aws_ecs_task_definition.go index bcfe8f398..a2c54aaf0 100644 --- a/builtin/providers/aws/resource_aws_ecs_task_definition.go +++ b/builtin/providers/aws/resource_aws_ecs_task_definition.go @@ -8,7 +8,6 @@ import ( "log" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ecs" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" @@ -91,7 +90,7 @@ func resourceAwsEcsTaskDefinitionCreate(d *schema.ResourceData, meta interface{} input.Volumes = volumes } - log.Printf("[DEBUG] Registering ECS task definition: %s", awsutil.StringValue(input)) + log.Printf("[DEBUG] Registering ECS task definition: %s", input) out, err := conn.RegisterTaskDefinition(&input) if err != nil { return err @@ -118,7 +117,7 @@ func resourceAwsEcsTaskDefinitionRead(d *schema.ResourceData, meta interface{}) if err != nil { return err } - log.Printf("[DEBUG] Received task definition %s", awsutil.StringValue(out)) + log.Printf("[DEBUG] Received task definition %s", out) taskDefinition := out.TaskDefinition diff --git a/builtin/providers/aws/resource_aws_elasticache_cluster.go b/builtin/providers/aws/resource_aws_elasticache_cluster.go index fa0d6b746..cd8ee0668 100644 --- a/builtin/providers/aws/resource_aws_elasticache_cluster.go +++ b/builtin/providers/aws/resource_aws_elasticache_cluster.go @@ -9,7 +9,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/elasticache" "github.com/aws/aws-sdk-go/service/iam" "github.com/hashicorp/terraform/helper/hashcode" @@ -160,10 +159,10 @@ func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{ req := &elasticache.CreateCacheClusterInput{ CacheClusterID: aws.String(clusterId), CacheNodeType: aws.String(nodeType), - NumCacheNodes: aws.Long(numNodes), + NumCacheNodes: aws.Int64(numNodes), Engine: aws.String(engine), EngineVersion: aws.String(engineVersion), - Port: aws.Long(port), + Port: aws.Int64(port), CacheSubnetGroupName: aws.String(subnetGroupName), CacheSecurityGroupNames: securityNames, SecurityGroupIDs: securityIds, @@ -216,7 +215,7 @@ func resourceAwsElasticacheClusterRead(d *schema.ResourceData, meta interface{}) conn := meta.(*AWSClient).elasticacheconn req := &elasticache.DescribeCacheClustersInput{ CacheClusterID: aws.String(d.Id()), - ShowCacheNodeInfo: aws.Boolean(true), + ShowCacheNodeInfo: aws.Bool(true), } res, err := conn.DescribeCacheClusters(req) @@ -281,7 +280,7 @@ func resourceAwsElasticacheClusterUpdate(d *schema.ResourceData, meta interface{ req := &elasticache.ModifyCacheClusterInput{ CacheClusterID: aws.String(d.Id()), - ApplyImmediately: aws.Boolean(d.Get("apply_immediately").(bool)), + ApplyImmediately: aws.Bool(d.Get("apply_immediately").(bool)), } requestUpdate := false @@ -308,12 +307,12 @@ func resourceAwsElasticacheClusterUpdate(d *schema.ResourceData, meta interface{ } if d.HasChange("num_cache_nodes") { - req.NumCacheNodes = aws.Long(int64(d.Get("num_cache_nodes").(int))) + req.NumCacheNodes = aws.Int64(int64(d.Get("num_cache_nodes").(int))) requestUpdate = true } if requestUpdate { - log.Printf("[DEBUG] Modifying ElastiCache Cluster (%s), opts:\n%s", d.Id(), awsutil.StringValue(req)) + log.Printf("[DEBUG] Modifying ElastiCache Cluster (%s), opts:\n%s", d.Id(), req) _, err := conn.ModifyCacheCluster(req) if err != nil { return fmt.Errorf("[WARN] Error updating ElastiCache cluster (%s), error: %s", d.Id(), err) @@ -348,7 +347,7 @@ func setCacheNodeData(d *schema.ResourceData, c *elasticache.CacheCluster) error for _, node := range sortedCacheNodes { if node.CacheNodeID == nil || node.Endpoint == nil || node.Endpoint.Address == nil || node.Endpoint.Port == nil { - return fmt.Errorf("Unexpected nil pointer in: %s", awsutil.StringValue(node)) + return fmt.Errorf("Unexpected nil pointer in: %s", node) } cacheNodeData = append(cacheNodeData, map[string]interface{}{ "id": *node.CacheNodeID, @@ -404,7 +403,7 @@ func cacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, give return func() (interface{}, string, error) { resp, err := conn.DescribeCacheClusters(&elasticache.DescribeCacheClustersInput{ CacheClusterID: aws.String(clusterID), - ShowCacheNodeInfo: aws.Boolean(true), + ShowCacheNodeInfo: aws.Bool(true), }) if err != nil { apierr := err.(awserr.Error) diff --git a/builtin/providers/aws/resource_aws_elasticache_parameter_group.go b/builtin/providers/aws/resource_aws_elasticache_parameter_group.go index 3574d5dcf..c730ff94f 100644 --- a/builtin/providers/aws/resource_aws_elasticache_parameter_group.go +++ b/builtin/providers/aws/resource_aws_elasticache_parameter_group.go @@ -65,7 +65,7 @@ func resourceAwsElasticacheParameterGroupCreate(d *schema.ResourceData, meta int createOpts := elasticache.CreateCacheParameterGroupInput{ CacheParameterGroupName: aws.String(d.Get("name").(string)), CacheParameterGroupFamily: aws.String(d.Get("family").(string)), - Description: aws.String(d.Get("description").(string)), + Description: aws.String(d.Get("description").(string)), } log.Printf("[DEBUG] Create Cache Parameter Group: %#v", createOpts) @@ -110,7 +110,7 @@ func resourceAwsElasticacheParameterGroupRead(d *schema.ResourceData, meta inter // Only include user customized parameters as there's hundreds of system/default ones describeParametersOpts := elasticache.DescribeCacheParametersInput{ CacheParameterGroupName: aws.String(d.Id()), - Source: aws.String("user"), + Source: aws.String("user"), } describeParametersResp, err := conn.DescribeCacheParameters(&describeParametersOpts) diff --git a/builtin/providers/aws/resource_aws_elb.go b/builtin/providers/aws/resource_aws_elb.go index 8819a14d0..c69d1b16f 100644 --- a/builtin/providers/aws/resource_aws_elb.go +++ b/builtin/providers/aws/resource_aws_elb.go @@ -429,10 +429,10 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error { LoadBalancerName: aws.String(d.Get("name").(string)), LoadBalancerAttributes: &elb.LoadBalancerAttributes{ CrossZoneLoadBalancing: &elb.CrossZoneLoadBalancing{ - Enabled: aws.Boolean(d.Get("cross_zone_load_balancing").(bool)), + Enabled: aws.Bool(d.Get("cross_zone_load_balancing").(bool)), }, ConnectionSettings: &elb.ConnectionSettings{ - IdleTimeout: aws.Long(int64(d.Get("idle_timeout").(int))), + IdleTimeout: aws.Int64(int64(d.Get("idle_timeout").(int))), }, }, } @@ -459,8 +459,8 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error { LoadBalancerName: aws.String(d.Get("name").(string)), LoadBalancerAttributes: &elb.LoadBalancerAttributes{ ConnectionDraining: &elb.ConnectionDraining{ - Enabled: aws.Boolean(true), - Timeout: aws.Long(int64(d.Get("connection_draining_timeout").(int))), + Enabled: aws.Bool(true), + Timeout: aws.Int64(int64(d.Get("connection_draining_timeout").(int))), }, }, } @@ -480,7 +480,7 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error { LoadBalancerName: aws.String(d.Get("name").(string)), LoadBalancerAttributes: &elb.LoadBalancerAttributes{ ConnectionDraining: &elb.ConnectionDraining{ - Enabled: aws.Boolean(d.Get("connection_draining").(bool)), + Enabled: aws.Bool(d.Get("connection_draining").(bool)), }, }, } @@ -500,11 +500,11 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error { configureHealthCheckOpts := elb.ConfigureHealthCheckInput{ LoadBalancerName: aws.String(d.Id()), HealthCheck: &elb.HealthCheck{ - HealthyThreshold: aws.Long(int64(check["healthy_threshold"].(int))), - UnhealthyThreshold: aws.Long(int64(check["unhealthy_threshold"].(int))), - Interval: aws.Long(int64(check["interval"].(int))), + HealthyThreshold: aws.Int64(int64(check["healthy_threshold"].(int))), + UnhealthyThreshold: aws.Int64(int64(check["unhealthy_threshold"].(int))), + Interval: aws.Int64(int64(check["interval"].(int))), Target: aws.String(check["target"].(string)), - Timeout: aws.Long(int64(check["timeout"].(int))), + Timeout: aws.Int64(int64(check["timeout"].(int))), }, } _, err := elbconn.ConfigureHealthCheck(&configureHealthCheckOpts) diff --git a/builtin/providers/aws/resource_aws_elb_test.go b/builtin/providers/aws/resource_aws_elb_test.go index ea56bf1da..e30707666 100644 --- a/builtin/providers/aws/resource_aws_elb_test.go +++ b/builtin/providers/aws/resource_aws_elb_test.go @@ -465,9 +465,9 @@ func testAccCheckAWSELBAttributes(conf *elb.LoadBalancerDescription) resource.Te } l := elb.Listener{ - InstancePort: aws.Long(int64(8000)), + InstancePort: aws.Int64(int64(8000)), InstanceProtocol: aws.String("HTTP"), - LoadBalancerPort: aws.Long(int64(80)), + LoadBalancerPort: aws.Int64(int64(80)), Protocol: aws.String("HTTP"), } @@ -503,10 +503,10 @@ func testAccCheckAWSELBAttributesHealthCheck(conf *elb.LoadBalancerDescription) } check := &elb.HealthCheck{ - Timeout: aws.Long(int64(30)), - UnhealthyThreshold: aws.Long(int64(5)), - HealthyThreshold: aws.Long(int64(5)), - Interval: aws.Long(int64(60)), + Timeout: aws.Int64(int64(30)), + UnhealthyThreshold: aws.Int64(int64(5)), + HealthyThreshold: aws.Int64(int64(5)), + Interval: aws.Int64(int64(60)), Target: aws.String("HTTP:8000/"), } diff --git a/builtin/providers/aws/resource_aws_flow_log.go b/builtin/providers/aws/resource_aws_flow_log.go index 39b3c7566..07fbd06b1 100644 --- a/builtin/providers/aws/resource_aws_flow_log.go +++ b/builtin/providers/aws/resource_aws_flow_log.go @@ -5,7 +5,6 @@ import ( "log" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/schema" ) @@ -94,7 +93,7 @@ func resourceAwsLogFlowCreate(d *schema.ResourceData, meta interface{}) error { } log.Printf( - "[DEBUG] Flow Log Create configuration: %s", awsutil.StringValue(opts)) + "[DEBUG] Flow Log Create configuration: %s", opts) resp, err := conn.CreateFlowLogs(opts) if err != nil { return fmt.Errorf("Error creating Flow Log for (%s), error: %s", resourceId, err) diff --git a/builtin/providers/aws/resource_aws_iam_policy.go b/builtin/providers/aws/resource_aws_iam_policy.go index 9ace92b21..cda5e5079 100644 --- a/builtin/providers/aws/resource_aws_iam_policy.go +++ b/builtin/providers/aws/resource_aws_iam_policy.go @@ -97,7 +97,7 @@ func resourceAwsIamPolicyUpdate(d *schema.ResourceData, meta interface{}) error request := &iam.CreatePolicyVersionInput{ PolicyARN: aws.String(d.Id()), PolicyDocument: aws.String(d.Get("policy").(string)), - SetAsDefault: aws.Boolean(true), + SetAsDefault: aws.Bool(true), } if _, err := iamconn.CreatePolicyVersion(request); err != nil { diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go index d6ec35af1..c828e1152 100644 --- a/builtin/providers/aws/resource_aws_instance.go +++ b/builtin/providers/aws/resource_aws_instance.go @@ -12,7 +12,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" @@ -334,8 +333,8 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { ImageID: instanceOpts.ImageID, InstanceType: instanceOpts.InstanceType, KeyName: instanceOpts.KeyName, - MaxCount: aws.Long(int64(1)), - MinCount: aws.Long(int64(1)), + MaxCount: aws.Int64(int64(1)), + MinCount: aws.Int64(int64(1)), NetworkInterfaces: instanceOpts.NetworkInterfaces, Placement: instanceOpts.Placement, PrivateIPAddress: instanceOpts.PrivateIPAddress, @@ -346,7 +345,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } // Create the instance - log.Printf("[DEBUG] Run configuration: %s", awsutil.StringValue(runOpts)) + log.Printf("[DEBUG] Run configuration: %s", runOpts) var runResp *ec2.Reservation for i := 0; i < 5; i++ { @@ -543,7 +542,7 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { _, err := conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeInput{ InstanceID: aws.String(d.Id()), SourceDestCheck: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(d.Get("source_dest_check").(bool)), + Value: aws.Bool(d.Get("source_dest_check").(bool)), }, }) if err != nil { @@ -571,7 +570,7 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { _, err := conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeInput{ InstanceID: aws.String(d.Id()), DisableAPITermination: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(d.Get("disable_api_termination").(bool)), + Value: aws.Bool(d.Get("disable_api_termination").(bool)), }, }) if err != nil { @@ -778,9 +777,9 @@ func fetchRootDeviceName(ami string, conn *ec2.EC2) (*string, error) { rootDeviceName = image.BlockDeviceMappings[0].DeviceName } - if rootDeviceName == nil { - return nil, fmt.Errorf("[WARN] Error finding Root Device Name for AMI (%s)", ami) - } + if rootDeviceName == nil { + return nil, fmt.Errorf("[WARN] Error finding Root Device Name for AMI (%s)", ami) + } return rootDeviceName, nil } @@ -794,7 +793,7 @@ func readBlockDeviceMappingsFromConfig( for _, v := range vL { bd := v.(map[string]interface{}) ebs := &ec2.EBSBlockDevice{ - DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)), + DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)), } if v, ok := bd["snapshot_id"].(string); ok && v != "" { @@ -802,11 +801,11 @@ func readBlockDeviceMappingsFromConfig( } if v, ok := bd["encrypted"].(bool); ok && v { - ebs.Encrypted = aws.Boolean(v) + ebs.Encrypted = aws.Bool(v) } if v, ok := bd["volume_size"].(int); ok && v != 0 { - ebs.VolumeSize = aws.Long(int64(v)) + ebs.VolumeSize = aws.Int64(int64(v)) } if v, ok := bd["volume_type"].(string); ok && v != "" { @@ -814,7 +813,7 @@ func readBlockDeviceMappingsFromConfig( } if v, ok := bd["iops"].(int); ok && v > 0 { - ebs.IOPS = aws.Long(int64(v)) + ebs.IOPS = aws.Int64(int64(v)) } blockDevices = append(blockDevices, &ec2.BlockDeviceMapping{ @@ -843,11 +842,11 @@ func readBlockDeviceMappingsFromConfig( for _, v := range vL { bd := v.(map[string]interface{}) ebs := &ec2.EBSBlockDevice{ - DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)), + DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)), } if v, ok := bd["volume_size"].(int); ok && v != 0 { - ebs.VolumeSize = aws.Long(int64(v)) + ebs.VolumeSize = aws.Int64(int64(v)) } if v, ok := bd["volume_type"].(string); ok && v != "" { @@ -855,7 +854,7 @@ func readBlockDeviceMappingsFromConfig( } if v, ok := bd["iops"].(int); ok && v > 0 { - ebs.IOPS = aws.Long(int64(v)) + ebs.IOPS = aws.Int64(int64(v)) } if dn, err := fetchRootDeviceName(d.Get("ami").(string), conn); err == nil { @@ -902,14 +901,14 @@ func buildAwsInstanceOpts( conn := meta.(*AWSClient).ec2conn opts := &awsInstanceOpts{ - DisableAPITermination: aws.Boolean(d.Get("disable_api_termination").(bool)), - EBSOptimized: aws.Boolean(d.Get("ebs_optimized").(bool)), + DisableAPITermination: aws.Bool(d.Get("disable_api_termination").(bool)), + EBSOptimized: aws.Bool(d.Get("ebs_optimized").(bool)), ImageID: aws.String(d.Get("ami").(string)), InstanceType: aws.String(d.Get("instance_type").(string)), } opts.Monitoring = &ec2.RunInstancesMonitoringEnabled{ - Enabled: aws.Boolean(d.Get("monitoring").(bool)), + Enabled: aws.Bool(d.Get("monitoring").(bool)), } opts.IAMInstanceProfile = &ec2.IAMInstanceProfileSpecification{ @@ -965,8 +964,8 @@ func buildAwsInstanceOpts( // to avoid: Network interfaces and an instance-level security groups may not be specified on // the same request ni := &ec2.InstanceNetworkInterfaceSpecification{ - AssociatePublicIPAddress: aws.Boolean(associatePublicIPAddress), - DeviceIndex: aws.Long(int64(0)), + AssociatePublicIPAddress: aws.Bool(associatePublicIPAddress), + DeviceIndex: aws.Int64(int64(0)), SubnetID: aws.String(subnetID), Groups: groups, } diff --git a/builtin/providers/aws/resource_aws_instance_test.go b/builtin/providers/aws/resource_aws_instance_test.go index c189a5963..15647b576 100644 --- a/builtin/providers/aws/resource_aws_instance_test.go +++ b/builtin/providers/aws/resource_aws_instance_test.go @@ -7,7 +7,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -47,7 +46,7 @@ func TestAccAWSInstance_basic(t *testing.T) { var err error vol, err = conn.CreateVolume(&ec2.CreateVolumeInput{ AvailabilityZone: aws.String("us-west-2a"), - Size: aws.Long(int64(5)), + Size: aws.Int64(int64(5)), }) return err }, @@ -467,8 +466,8 @@ func TestAccAWSInstance_keyPairCheck(t *testing.T) { if v.KeyName == nil { return fmt.Errorf("No Key Pair found, expected(%s)", keyName) } - if *v.KeyName != keyName { - return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, awsutil.StringValue(v.KeyName)) + if v.KeyName != nil && *v.KeyName != keyName { + return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, *v.KeyName) } return nil diff --git a/builtin/providers/aws/resource_aws_kinesis_stream.go b/builtin/providers/aws/resource_aws_kinesis_stream.go index f4c84f803..4f4a79e6b 100644 --- a/builtin/providers/aws/resource_aws_kinesis_stream.go +++ b/builtin/providers/aws/resource_aws_kinesis_stream.go @@ -43,7 +43,7 @@ func resourceAwsKinesisStreamCreate(d *schema.ResourceData, meta interface{}) er conn := meta.(*AWSClient).kinesisconn sn := d.Get("name").(string) createOpts := &kinesis.CreateStreamInput{ - ShardCount: aws.Long(int64(d.Get("shard_count").(int))), + ShardCount: aws.Int64(int64(d.Get("shard_count").(int))), StreamName: aws.String(sn), } @@ -82,7 +82,7 @@ func resourceAwsKinesisStreamRead(d *schema.ResourceData, meta interface{}) erro conn := meta.(*AWSClient).kinesisconn describeOpts := &kinesis.DescribeStreamInput{ StreamName: aws.String(d.Get("name").(string)), - Limit: aws.Long(1), + Limit: aws.Int64(1), } resp, err := conn.DescribeStream(describeOpts) if err != nil { @@ -138,7 +138,7 @@ func streamStateRefreshFunc(conn *kinesis.Kinesis, sn string) resource.StateRefr return func() (interface{}, string, error) { describeOpts := &kinesis.DescribeStreamInput{ StreamName: aws.String(sn), - Limit: aws.Long(1), + Limit: aws.Int64(1), } resp, err := conn.DescribeStream(describeOpts) if err != nil { diff --git a/builtin/providers/aws/resource_aws_kinesis_stream_test.go b/builtin/providers/aws/resource_aws_kinesis_stream_test.go index 814ea92d2..77d0b0588 100644 --- a/builtin/providers/aws/resource_aws_kinesis_stream_test.go +++ b/builtin/providers/aws/resource_aws_kinesis_stream_test.go @@ -46,7 +46,7 @@ func testAccCheckKinesisStreamExists(n string, stream *kinesis.StreamDescription conn := testAccProvider.Meta().(*AWSClient).kinesisconn describeOpts := &kinesis.DescribeStreamInput{ StreamName: aws.String(rs.Primary.Attributes["name"]), - Limit: aws.Long(1), + Limit: aws.Int64(1), } resp, err := conn.DescribeStream(describeOpts) if err != nil { @@ -84,7 +84,7 @@ func testAccCheckKinesisStreamDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).kinesisconn describeOpts := &kinesis.DescribeStreamInput{ StreamName: aws.String(rs.Primary.Attributes["name"]), - Limit: aws.Long(1), + Limit: aws.Int64(1), } resp, err := conn.DescribeStream(describeOpts) if err == nil { diff --git a/builtin/providers/aws/resource_aws_lambda_function.go b/builtin/providers/aws/resource_aws_lambda_function.go index 72dab0154..84d1264bd 100644 --- a/builtin/providers/aws/resource_aws_lambda_function.go +++ b/builtin/providers/aws/resource_aws_lambda_function.go @@ -112,10 +112,10 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e Description: aws.String(d.Get("description").(string)), FunctionName: aws.String(functionName), Handler: aws.String(d.Get("handler").(string)), - MemorySize: aws.Long(int64(d.Get("memory_size").(int))), + MemorySize: aws.Int64(int64(d.Get("memory_size").(int))), Role: aws.String(iamRole), Runtime: aws.String(d.Get("runtime").(string)), - Timeout: aws.Long(int64(d.Get("timeout").(int))), + Timeout: aws.Int64(int64(d.Get("timeout").(int))), } for i := 0; i < 5; i++ { diff --git a/builtin/providers/aws/resource_aws_launch_configuration.go b/builtin/providers/aws/resource_aws_launch_configuration.go index 85630aa5a..f234d0249 100644 --- a/builtin/providers/aws/resource_aws_launch_configuration.go +++ b/builtin/providers/aws/resource_aws_launch_configuration.go @@ -264,7 +264,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface LaunchConfigurationName: aws.String(d.Get("name").(string)), ImageID: aws.String(d.Get("image_id").(string)), InstanceType: aws.String(d.Get("instance_type").(string)), - EBSOptimized: aws.Boolean(d.Get("ebs_optimized").(bool)), + EBSOptimized: aws.Bool(d.Get("ebs_optimized").(bool)), } if v, ok := d.GetOk("user_data"); ok { @@ -273,7 +273,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface } createLaunchConfigurationOpts.InstanceMonitoring = &autoscaling.InstanceMonitoring{ - Enabled: aws.Boolean(d.Get("enable_monitoring").(bool)), + Enabled: aws.Bool(d.Get("enable_monitoring").(bool)), } if v, ok := d.GetOk("iam_instance_profile"); ok { @@ -285,7 +285,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface } if v, ok := d.GetOk("associate_public_ip_address"); ok { - createLaunchConfigurationOpts.AssociatePublicIPAddress = aws.Boolean(v.(bool)) + createLaunchConfigurationOpts.AssociatePublicIPAddress = aws.Bool(v.(bool)) } if v, ok := d.GetOk("key_name"); ok { @@ -308,7 +308,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface for _, v := range vL { bd := v.(map[string]interface{}) ebs := &autoscaling.EBS{ - DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)), + DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)), } if v, ok := bd["snapshot_id"].(string); ok && v != "" { @@ -316,7 +316,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface } if v, ok := bd["volume_size"].(int); ok && v != 0 { - ebs.VolumeSize = aws.Long(int64(v)) + ebs.VolumeSize = aws.Int64(int64(v)) } if v, ok := bd["volume_type"].(string); ok && v != "" { @@ -324,7 +324,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface } if v, ok := bd["iops"].(int); ok && v > 0 { - ebs.IOPS = aws.Long(int64(v)) + ebs.IOPS = aws.Int64(int64(v)) } blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{ @@ -353,11 +353,11 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface for _, v := range vL { bd := v.(map[string]interface{}) ebs := &autoscaling.EBS{ - DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)), + DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)), } if v, ok := bd["volume_size"].(int); ok && v != 0 { - ebs.VolumeSize = aws.Long(int64(v)) + ebs.VolumeSize = aws.Int64(int64(v)) } if v, ok := bd["volume_type"].(string); ok && v != "" { @@ -365,7 +365,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface } if v, ok := bd["iops"].(int); ok && v > 0 { - ebs.IOPS = aws.Long(int64(v)) + ebs.IOPS = aws.Int64(int64(v)) } if dn, err := fetchRootDeviceName(d.Get("image_id").(string), ec2conn); err == nil { diff --git a/builtin/providers/aws/resource_aws_lb_cookie_stickiness_policy.go b/builtin/providers/aws/resource_aws_lb_cookie_stickiness_policy.go index fdc8ec303..50c6186de 100644 --- a/builtin/providers/aws/resource_aws_lb_cookie_stickiness_policy.go +++ b/builtin/providers/aws/resource_aws_lb_cookie_stickiness_policy.go @@ -53,7 +53,7 @@ func resourceAwsLBCookieStickinessPolicyCreate(d *schema.ResourceData, meta inte // Provision the LBStickinessPolicy lbspOpts := &elb.CreateLBCookieStickinessPolicyInput{ - CookieExpirationPeriod: aws.Long(int64(d.Get("cookie_expiration_period").(int))), + CookieExpirationPeriod: aws.Int64(int64(d.Get("cookie_expiration_period").(int))), LoadBalancerName: aws.String(d.Get("load_balancer").(string)), PolicyName: aws.String(d.Get("name").(string)), } @@ -64,7 +64,7 @@ func resourceAwsLBCookieStickinessPolicyCreate(d *schema.ResourceData, meta inte setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ LoadBalancerName: aws.String(d.Get("load_balancer").(string)), - LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))), + LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))), PolicyNames: []*string{aws.String(d.Get("name").(string))}, } @@ -129,7 +129,7 @@ func resourceAwsLBCookieStickinessPolicyDelete(d *schema.ResourceData, meta inte // policy itself. setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ LoadBalancerName: aws.String(d.Get("load_balancer").(string)), - LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))), + LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))), PolicyNames: []*string{}, } diff --git a/builtin/providers/aws/resource_aws_network_interface.go b/builtin/providers/aws/resource_aws_network_interface.go index a26e668d9..acf3a365b 100644 --- a/builtin/providers/aws/resource_aws_network_interface.go +++ b/builtin/providers/aws/resource_aws_network_interface.go @@ -175,7 +175,7 @@ func resourceAwsNetworkInterfaceDetach(oa *schema.Set, meta interface{}, eniId s old_attachment := oa.List()[0].(map[string]interface{}) detach_request := &ec2.DetachNetworkInterfaceInput{ AttachmentID: aws.String(old_attachment["attachment_id"].(string)), - Force: aws.Boolean(true), + Force: aws.Bool(true), } conn := meta.(*AWSClient).ec2conn _, detach_err := conn.DetachNetworkInterface(detach_request) @@ -216,7 +216,7 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) new_attachment := na.(*schema.Set).List()[0].(map[string]interface{}) di := new_attachment["device_index"].(int) attach_request := &ec2.AttachNetworkInterfaceInput{ - DeviceIndex: aws.Long(int64(di)), + DeviceIndex: aws.Int64(int64(di)), InstanceID: aws.String(new_attachment["instance"].(string)), NetworkInterfaceID: aws.String(d.Id()), } @@ -231,7 +231,7 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) request := &ec2.ModifyNetworkInterfaceAttributeInput{ NetworkInterfaceID: aws.String(d.Id()), - SourceDestCheck: &ec2.AttributeBooleanValue{Value: aws.Boolean(d.Get("source_dest_check").(bool))}, + SourceDestCheck: &ec2.AttributeBooleanValue{Value: aws.Bool(d.Get("source_dest_check").(bool))}, } _, err := conn.ModifyNetworkInterfaceAttribute(request) diff --git a/builtin/providers/aws/resource_aws_route53_health_check.go b/builtin/providers/aws/resource_aws_route53_health_check.go index cd48a30b7..706e8da58 100644 --- a/builtin/providers/aws/resource_aws_route53_health_check.go +++ b/builtin/providers/aws/resource_aws_route53_health_check.go @@ -68,7 +68,7 @@ func resourceAwsRoute53HealthCheckUpdate(d *schema.ResourceData, meta interface{ } if d.HasChange("failure_threshold") { - updateHealthCheck.FailureThreshold = aws.Long(int64(d.Get("failure_threshold").(int))) + updateHealthCheck.FailureThreshold = aws.Int64(int64(d.Get("failure_threshold").(int))) } if d.HasChange("fqdn") { @@ -76,7 +76,7 @@ func resourceAwsRoute53HealthCheckUpdate(d *schema.ResourceData, meta interface{ } if d.HasChange("port") { - updateHealthCheck.Port = aws.Long(int64(d.Get("port").(int))) + updateHealthCheck.Port = aws.Int64(int64(d.Get("port").(int))) } if d.HasChange("resource_path") { @@ -104,8 +104,8 @@ func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{ healthConfig := &route53.HealthCheckConfig{ Type: aws.String(d.Get("type").(string)), - FailureThreshold: aws.Long(int64(d.Get("failure_threshold").(int))), - RequestInterval: aws.Long(int64(d.Get("request_interval").(int))), + FailureThreshold: aws.Int64(int64(d.Get("failure_threshold").(int))), + RequestInterval: aws.Int64(int64(d.Get("request_interval").(int))), } if v, ok := d.GetOk("fqdn"); ok { @@ -121,7 +121,7 @@ func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{ } if v, ok := d.GetOk("port"); ok { - healthConfig.Port = aws.Long(int64(v.(int))) + healthConfig.Port = aws.Int64(int64(v.(int))) } if v, ok := d.GetOk("resource_path"); ok { diff --git a/builtin/providers/aws/resource_aws_route53_record.go b/builtin/providers/aws/resource_aws_route53_record.go index d4eeafe18..78446f35c 100644 --- a/builtin/providers/aws/resource_aws_route53_record.go +++ b/builtin/providers/aws/resource_aws_route53_record.go @@ -367,7 +367,7 @@ func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) ( } if v, ok := d.GetOk("ttl"); ok { - rec.TTL = aws.Long(int64(v.(int))) + rec.TTL = aws.Int64(int64(v.(int))) } // Resource records @@ -385,7 +385,7 @@ func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) ( alias := aliases[0].(map[string]interface{}) rec.AliasTarget = &route53.AliasTarget{ DNSName: aws.String(alias["name"].(string)), - EvaluateTargetHealth: aws.Boolean(alias["evaluate_target_health"].(bool)), + EvaluateTargetHealth: aws.Bool(alias["evaluate_target_health"].(bool)), HostedZoneID: aws.String(alias["zone_id"].(string)), } log.Printf("[DEBUG] Creating alias: %#v", alias) @@ -408,7 +408,7 @@ func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) ( } if v, ok := d.GetOk("weight"); ok { - rec.Weight = aws.Long(int64(v.(int))) + rec.Weight = aws.Int64(int64(v.(int))) } if v, ok := d.GetOk("set_identifier"); ok { diff --git a/builtin/providers/aws/resource_aws_security_group.go b/builtin/providers/aws/resource_aws_security_group.go index b418a1759..503f6657a 100644 --- a/builtin/providers/aws/resource_aws_security_group.go +++ b/builtin/providers/aws/resource_aws_security_group.go @@ -223,8 +223,8 @@ func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) er GroupID: createResp.GroupID, IPPermissions: []*ec2.IPPermission{ &ec2.IPPermission{ - FromPort: aws.Long(int64(0)), - ToPort: aws.Long(int64(0)), + FromPort: aws.Int64(int64(0)), + ToPort: aws.Int64(int64(0)), IPRanges: []*ec2.IPRange{ &ec2.IPRange{ CIDRIP: aws.String("0.0.0.0/0"), diff --git a/builtin/providers/aws/resource_aws_security_group_rule.go b/builtin/providers/aws/resource_aws_security_group_rule.go index 927030b70..e3795c077 100644 --- a/builtin/providers/aws/resource_aws_security_group_rule.go +++ b/builtin/providers/aws/resource_aws_security_group_rule.go @@ -9,7 +9,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/schema" @@ -98,7 +97,7 @@ func resourceAwsSecurityGroupRuleCreate(d *schema.ResourceData, meta interface{} switch ruleType { case "ingress": log.Printf("[DEBUG] Authorizing security group %s %s rule: %s", - sg_id, "Ingress", awsutil.StringValue(perm)) + sg_id, "Ingress", perm) req := &ec2.AuthorizeSecurityGroupIngressInput{ GroupID: sg.GroupID, @@ -213,7 +212,7 @@ func resourceAwsSecurityGroupRuleDelete(d *schema.ResourceData, meta interface{} switch ruleType { case "ingress": log.Printf("[DEBUG] Revoking rule (%s) from security group %s:\n%s", - "ingress", sg_id, awsutil.StringValue(perm)) + "ingress", sg_id, perm) req := &ec2.RevokeSecurityGroupIngressInput{ GroupID: sg.GroupID, IPPermissions: []*ec2.IPPermission{perm}, @@ -330,8 +329,8 @@ func ipPermissionIDHash(ruleType string, ip *ec2.IPPermission) string { func expandIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup) *ec2.IPPermission { var perm ec2.IPPermission - perm.FromPort = aws.Long(int64(d.Get("from_port").(int))) - perm.ToPort = aws.Long(int64(d.Get("to_port").(int))) + perm.FromPort = aws.Int64(int64(d.Get("from_port").(int))) + perm.ToPort = aws.Int64(int64(d.Get("to_port").(int))) perm.IPProtocol = aws.String(d.Get("protocol").(string)) // build a group map that behaves like a set diff --git a/builtin/providers/aws/resource_aws_security_group_rule_migrate.go b/builtin/providers/aws/resource_aws_security_group_rule_migrate.go index 30eb8c09f..bff46684b 100644 --- a/builtin/providers/aws/resource_aws_security_group_rule_migrate.go +++ b/builtin/providers/aws/resource_aws_security_group_rule_migrate.go @@ -56,8 +56,8 @@ func migrateExpandIPPerm(attrs map[string]string) (*ec2.IPPermission, error) { return nil, fmt.Errorf("Error converting from_port in Security Group migration") } - perm.ToPort = aws.Long(int64(tp)) - perm.FromPort = aws.Long(int64(fp)) + perm.ToPort = aws.Int64(int64(tp)) + perm.FromPort = aws.Int64(int64(fp)) perm.IPProtocol = aws.String(attrs["protocol"]) groups := make(map[string]bool) diff --git a/builtin/providers/aws/resource_aws_security_group_rule_test.go b/builtin/providers/aws/resource_aws_security_group_rule_test.go index 595886e18..053838959 100644 --- a/builtin/providers/aws/resource_aws_security_group_rule_test.go +++ b/builtin/providers/aws/resource_aws_security_group_rule_test.go @@ -7,7 +7,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -16,8 +15,8 @@ import ( func TestIpPermissionIDHash(t *testing.T) { simple := &ec2.IPPermission{ IPProtocol: aws.String("tcp"), - FromPort: aws.Long(int64(80)), - ToPort: aws.Long(int64(8000)), + FromPort: aws.Int64(int64(80)), + ToPort: aws.Int64(int64(8000)), IPRanges: []*ec2.IPRange{ &ec2.IPRange{ CIDRIP: aws.String("10.0.0.0/8"), @@ -27,8 +26,8 @@ func TestIpPermissionIDHash(t *testing.T) { egress := &ec2.IPPermission{ IPProtocol: aws.String("tcp"), - FromPort: aws.Long(int64(80)), - ToPort: aws.Long(int64(8000)), + FromPort: aws.Int64(int64(80)), + ToPort: aws.Int64(int64(8000)), IPRanges: []*ec2.IPRange{ &ec2.IPRange{ CIDRIP: aws.String("10.0.0.0/8"), @@ -47,8 +46,8 @@ func TestIpPermissionIDHash(t *testing.T) { vpc_security_group_source := &ec2.IPPermission{ IPProtocol: aws.String("tcp"), - FromPort: aws.Long(int64(80)), - ToPort: aws.Long(int64(8000)), + FromPort: aws.Int64(int64(80)), + ToPort: aws.Int64(int64(8000)), UserIDGroupPairs: []*ec2.UserIDGroupPair{ &ec2.UserIDGroupPair{ UserID: aws.String("987654321"), @@ -67,8 +66,8 @@ func TestIpPermissionIDHash(t *testing.T) { security_group_source := &ec2.IPPermission{ IPProtocol: aws.String("tcp"), - FromPort: aws.Long(int64(80)), - ToPort: aws.Long(int64(8000)), + FromPort: aws.Int64(int64(80)), + ToPort: aws.Int64(int64(8000)), UserIDGroupPairs: []*ec2.UserIDGroupPair{ &ec2.UserIDGroupPair{ UserID: aws.String("987654321"), @@ -101,7 +100,7 @@ func TestIpPermissionIDHash(t *testing.T) { for _, tc := range cases { actual := ipPermissionIDHash(tc.Type, tc.Input) if actual != tc.Output { - t.Errorf("input: %s - %s\noutput: %s", tc.Type, awsutil.StringValue(tc.Input), actual) + t.Errorf("input: %s - %s\noutput: %s", tc.Type, tc.Input, actual) } } } @@ -323,8 +322,8 @@ func testAccCheckAWSSecurityGroupRuleExists(n string, group *ec2.SecurityGroup) func testAccCheckAWSSecurityGroupRuleAttributes(group *ec2.SecurityGroup, ruleType string) resource.TestCheckFunc { return func(s *terraform.State) error { p := &ec2.IPPermission{ - FromPort: aws.Long(80), - ToPort: aws.Long(8000), + FromPort: aws.Int64(80), + ToPort: aws.Int64(8000), IPProtocol: aws.String("tcp"), IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}}, } diff --git a/builtin/providers/aws/resource_aws_security_group_test.go b/builtin/providers/aws/resource_aws_security_group_test.go index d3a55da5a..2bca43e65 100644 --- a/builtin/providers/aws/resource_aws_security_group_test.go +++ b/builtin/providers/aws/resource_aws_security_group_test.go @@ -356,8 +356,8 @@ func testAccCheckAWSSecurityGroupExists(n string, group *ec2.SecurityGroup) reso func testAccCheckAWSSecurityGroupAttributes(group *ec2.SecurityGroup) resource.TestCheckFunc { return func(s *terraform.State) error { p := &ec2.IPPermission{ - FromPort: aws.Long(80), - ToPort: aws.Long(8000), + FromPort: aws.Int64(80), + ToPort: aws.Int64(8000), IPProtocol: aws.String("tcp"), IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}}, } @@ -449,14 +449,14 @@ func testAccCheckAWSSecurityGroupAttributesChanged(group *ec2.SecurityGroup) res return func(s *terraform.State) error { p := []*ec2.IPPermission{ &ec2.IPPermission{ - FromPort: aws.Long(80), - ToPort: aws.Long(9000), + FromPort: aws.Int64(80), + ToPort: aws.Int64(9000), IPProtocol: aws.String("tcp"), IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}}, }, &ec2.IPPermission{ - FromPort: aws.Long(80), - ToPort: aws.Long(8000), + FromPort: aws.Int64(80), + ToPort: aws.Int64(8000), IPProtocol: aws.String("tcp"), IPRanges: []*ec2.IPRange{ &ec2.IPRange{ diff --git a/builtin/providers/aws/resource_aws_spot_instance_request.go b/builtin/providers/aws/resource_aws_spot_instance_request.go index bed4c42cb..e98cc795a 100644 --- a/builtin/providers/aws/resource_aws_spot_instance_request.go +++ b/builtin/providers/aws/resource_aws_spot_instance_request.go @@ -7,7 +7,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -78,7 +77,7 @@ func resourceAwsSpotInstanceRequestCreate(d *schema.ResourceData, meta interface // Though the AWS API supports creating spot instance requests for multiple // instances, for TF purposes we fix this to one instance per request. // Users can get equivalent behavior out of TF's "count" meta-parameter. - InstanceCount: aws.Long(1), + InstanceCount: aws.Int64(1), LaunchSpecification: &ec2.RequestSpotLaunchSpecification{ BlockDeviceMappings: instanceOpts.BlockDeviceMappings, @@ -95,14 +94,14 @@ func resourceAwsSpotInstanceRequestCreate(d *schema.ResourceData, meta interface } // Make the spot instance request - log.Printf("[DEBUG] Requesting spot bid opts: %s", awsutil.StringValue(spotOpts)) + log.Printf("[DEBUG] Requesting spot bid opts: %s", spotOpts) resp, err := conn.RequestSpotInstances(spotOpts) if err != nil { return fmt.Errorf("Error requesting spot instances: %s", err) } if len(resp.SpotInstanceRequests) != 1 { return fmt.Errorf( - "Expected response with length 1, got: %s", awsutil.StringValue(resp)) + "Expected response with length 1, got: %s", resp) } sir := *resp.SpotInstanceRequests[0] @@ -123,7 +122,7 @@ func resourceAwsSpotInstanceRequestCreate(d *schema.ResourceData, meta interface _, err = spotStateConf.WaitForState() if err != nil { - return fmt.Errorf("Error while waiting for spot request (%s) to resolve: %s", awsutil.StringValue(sir), err) + return fmt.Errorf("Error while waiting for spot request (%s) to resolve: %s", sir, err) } } diff --git a/builtin/providers/aws/resource_aws_subnet.go b/builtin/providers/aws/resource_aws_subnet.go index 326ddc28d..454e5e2ae 100644 --- a/builtin/providers/aws/resource_aws_subnet.go +++ b/builtin/providers/aws/resource_aws_subnet.go @@ -137,7 +137,7 @@ func resourceAwsSubnetUpdate(d *schema.ResourceData, meta interface{}) error { modifyOpts := &ec2.ModifySubnetAttributeInput{ SubnetID: aws.String(d.Id()), MapPublicIPOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(d.Get("map_public_ip_on_launch").(bool)), + Value: aws.Bool(d.Get("map_public_ip_on_launch").(bool)), }, } diff --git a/builtin/providers/aws/resource_aws_volume_attachment.go b/builtin/providers/aws/resource_aws_volume_attachment.go index 6822ebd28..4188a3a50 100644 --- a/builtin/providers/aws/resource_aws_volume_attachment.go +++ b/builtin/providers/aws/resource_aws_volume_attachment.go @@ -157,7 +157,7 @@ func resourceAwsVolumeAttachmentDelete(d *schema.ResourceData, meta interface{}) Device: aws.String(d.Get("device_name").(string)), InstanceID: aws.String(iID), VolumeID: aws.String(vID), - Force: aws.Boolean(d.Get("force_detach").(bool)), + Force: aws.Bool(d.Get("force_detach").(bool)), } _, err := conn.DetachVolume(opts) diff --git a/builtin/providers/aws/resource_aws_vpn_connection.go b/builtin/providers/aws/resource_aws_vpn_connection.go index a97cd7559..731458660 100644 --- a/builtin/providers/aws/resource_aws_vpn_connection.go +++ b/builtin/providers/aws/resource_aws_vpn_connection.go @@ -143,7 +143,7 @@ func resourceAwsVpnConnectionCreate(d *schema.ResourceData, meta interface{}) er conn := meta.(*AWSClient).ec2conn connectOpts := &ec2.VPNConnectionOptionsSpecification{ - StaticRoutesOnly: aws.Boolean(d.Get("static_routes_only").(bool)), + StaticRoutesOnly: aws.Bool(d.Get("static_routes_only").(bool)), } createOpts := &ec2.CreateVPNConnectionInput{ diff --git a/builtin/providers/aws/structure.go b/builtin/providers/aws/structure.go index b22a0f1c8..bbcc9ae6f 100644 --- a/builtin/providers/aws/structure.go +++ b/builtin/providers/aws/structure.go @@ -94,7 +94,7 @@ func expandEcsLoadBalancers(configured []interface{}) []*ecs.LoadBalancer { l := &ecs.LoadBalancer{ ContainerName: aws.String(data["container_name"].(string)), - ContainerPort: aws.Long(int64(data["container_port"].(int))), + ContainerPort: aws.Int64(int64(data["container_port"].(int))), LoadBalancerName: aws.String(data["elb_name"].(string)), } @@ -117,8 +117,8 @@ func expandIPPerms( var perm ec2.IPPermission m := mRaw.(map[string]interface{}) - perm.FromPort = aws.Long(int64(m["from_port"].(int))) - perm.ToPort = aws.Long(int64(m["to_port"].(int))) + perm.FromPort = aws.Int64(int64(m["from_port"].(int))) + perm.ToPort = aws.Int64(int64(m["to_port"].(int))) perm.IPProtocol = aws.String(m["protocol"].(string)) // When protocol is "-1", AWS won't store any ports for the @@ -405,7 +405,7 @@ func expandPrivateIPAddesses(ips []interface{}) []*ec2.PrivateIPAddressSpecifica PrivateIPAddress: aws.String(v.(string)), } - new_private_ip.Primary = aws.Boolean(i == 0) + new_private_ip.Primary = aws.Bool(i == 0) dtos = append(dtos, new_private_ip) } diff --git a/builtin/providers/aws/structure_test.go b/builtin/providers/aws/structure_test.go index 64bf8c52c..261d55a06 100644 --- a/builtin/providers/aws/structure_test.go +++ b/builtin/providers/aws/structure_test.go @@ -70,8 +70,8 @@ func TestexpandIPPerms(t *testing.T) { expected := []ec2.IPPermission{ ec2.IPPermission{ IPProtocol: aws.String("icmp"), - FromPort: aws.Long(int64(1)), - ToPort: aws.Long(int64(-1)), + FromPort: aws.Int64(int64(1)), + ToPort: aws.Int64(int64(-1)), IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("0.0.0.0/0")}}, UserIDGroupPairs: []*ec2.UserIDGroupPair{ &ec2.UserIDGroupPair{ @@ -85,8 +85,8 @@ func TestexpandIPPerms(t *testing.T) { }, ec2.IPPermission{ IPProtocol: aws.String("icmp"), - FromPort: aws.Long(int64(1)), - ToPort: aws.Long(int64(-1)), + FromPort: aws.Int64(int64(1)), + ToPort: aws.Int64(int64(-1)), UserIDGroupPairs: []*ec2.UserIDGroupPair{ &ec2.UserIDGroupPair{ UserID: aws.String("foo"), @@ -149,8 +149,8 @@ func TestExpandIPPerms_NegOneProtocol(t *testing.T) { expected := []ec2.IPPermission{ ec2.IPPermission{ IPProtocol: aws.String("-1"), - FromPort: aws.Long(int64(0)), - ToPort: aws.Long(int64(0)), + FromPort: aws.Int64(int64(0)), + ToPort: aws.Int64(int64(0)), IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("0.0.0.0/0")}}, UserIDGroupPairs: []*ec2.UserIDGroupPair{ &ec2.UserIDGroupPair{ @@ -245,8 +245,8 @@ func TestExpandIPPerms_nonVPC(t *testing.T) { expected := []ec2.IPPermission{ ec2.IPPermission{ IPProtocol: aws.String("icmp"), - FromPort: aws.Long(int64(1)), - ToPort: aws.Long(int64(-1)), + FromPort: aws.Int64(int64(1)), + ToPort: aws.Int64(int64(-1)), IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("0.0.0.0/0")}}, UserIDGroupPairs: []*ec2.UserIDGroupPair{ &ec2.UserIDGroupPair{ @@ -259,8 +259,8 @@ func TestExpandIPPerms_nonVPC(t *testing.T) { }, ec2.IPPermission{ IPProtocol: aws.String("icmp"), - FromPort: aws.Long(int64(1)), - ToPort: aws.Long(int64(-1)), + FromPort: aws.Int64(int64(1)), + ToPort: aws.Int64(int64(-1)), UserIDGroupPairs: []*ec2.UserIDGroupPair{ &ec2.UserIDGroupPair{ GroupName: aws.String("foo"), @@ -302,8 +302,8 @@ func TestexpandListeners(t *testing.T) { } expected := &elb.Listener{ - InstancePort: aws.Long(int64(8000)), - LoadBalancerPort: aws.Long(int64(80)), + InstancePort: aws.Int64(int64(8000)), + LoadBalancerPort: aws.Int64(int64(80)), InstanceProtocol: aws.String("http"), Protocol: aws.String("http"), } @@ -324,11 +324,11 @@ func TestflattenHealthCheck(t *testing.T) { }{ { Input: &elb.HealthCheck{ - UnhealthyThreshold: aws.Long(int64(10)), - HealthyThreshold: aws.Long(int64(10)), + UnhealthyThreshold: aws.Int64(int64(10)), + HealthyThreshold: aws.Int64(int64(10)), Target: aws.String("HTTP:80/"), - Timeout: aws.Long(int64(30)), - Interval: aws.Long(int64(30)), + Timeout: aws.Int64(int64(30)), + Interval: aws.Int64(int64(30)), }, Output: []map[string]interface{}{ map[string]interface{}{ @@ -570,7 +570,7 @@ func TestexpandPrivateIPAddesses(t *testing.T) { func TestflattenAttachment(t *testing.T) { expanded := &ec2.NetworkInterfaceAttachment{ InstanceID: aws.String("i-00001"), - DeviceIndex: aws.Long(int64(1)), + DeviceIndex: aws.Int64(int64(1)), AttachmentID: aws.String("at-002"), } diff --git a/builtin/providers/aws/tags.go b/builtin/providers/aws/tags.go index 3d7aff9b8..df5d9e2a7 100644 --- a/builtin/providers/aws/tags.go +++ b/builtin/providers/aws/tags.go @@ -4,7 +4,6 @@ import ( "log" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awsutil" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/schema" ) @@ -39,7 +38,7 @@ func setTags(conn *ec2.EC2, d *schema.ResourceData) error { } } if len(create) > 0 { - log.Printf("[DEBUG] Creating tags: %s for %s", awsutil.StringValue(create), d.Id()) + log.Printf("[DEBUG] Creating tags: %s for %s", create, d.Id()) _, err := conn.CreateTags(&ec2.CreateTagsInput{ Resources: []*string{aws.String(d.Id())}, Tags: create, diff --git a/state/remote/s3.go b/state/remote/s3.go index c98fe9712..4d2b57592 100644 --- a/state/remote/s3.go +++ b/state/remote/s3.go @@ -67,7 +67,7 @@ func s3Factory(conf map[string]string) (Client, error) { awsConfig := &aws.Config{ Credentials: credentialsProvider, - Region: regionName, + Region: aws.String(regionName), } nativeClient := s3.New(awsConfig) diff --git a/state/remote/s3_test.go b/state/remote/s3_test.go index d9e99982e..e61d44b9e 100644 --- a/state/remote/s3_test.go +++ b/state/remote/s3_test.go @@ -43,7 +43,7 @@ func TestS3Factory(t *testing.T) { s3Client := client.(*S3Client) - if s3Client.nativeClient.Config.Region != "us-west-1" { + if *s3Client.nativeClient.Config.Region != "us-west-1" { t.Fatalf("Incorrect region was populated") } if s3Client.bucketName != "foo" { From 5ebbda3334006ef84c3ac7ea9cab31f121d851a0 Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Tue, 28 Jul 2015 17:09:56 -0500 Subject: [PATCH 54/73] core: fix crash on provider warning When a provider validation only returns a warning, we were cutting the evaltree short by returning an error. This is fine during a `walkValidate` but was causing trouble during `walkPlan` and `walkApply`. fixes #2870 --- terraform/context_apply_test.go | 40 +++++++++++++++++++ terraform/evaltree_provider.go | 29 +++++++++++++- .../apply-provider-warning/main.tf | 1 + 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 terraform/test-fixtures/apply-provider-warning/main.tf diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index ac252abd2..4b2113d63 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -78,6 +78,46 @@ func TestContext2Apply_providerAlias(t *testing.T) { } } +// GH-2870 +func TestContext2Apply_providerWarning(t *testing.T) { + m := testModule(t, "apply-provider-warning") + p := testProvider("aws") + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + p.ValidateFn = func(c *ResourceConfig) (ws []string, es []error) { + ws = append(ws, "Just a warning") + return + } + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + }) + + if _, err := ctx.Plan(); err != nil { + t.Fatalf("err: %s", err) + } + + state, err := ctx.Apply() + if err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(state.String()) + expected := strings.TrimSpace(` +aws_instance.foo: + ID = foo + `) + if actual != expected { + t.Fatalf("got: \n%s\n\nexpected:\n%s", actual, expected) + } + + if !p.ConfigureCalled { + t.Fatalf("provider Configure() was never called!") + } +} + func TestContext2Apply_emptyModule(t *testing.T) { m := testModule(t, "apply-empty-module") p := testProvider("aws") diff --git a/terraform/evaltree_provider.go b/terraform/evaltree_provider.go index 1910bc091..99e3ccb1e 100644 --- a/terraform/evaltree_provider.go +++ b/terraform/evaltree_provider.go @@ -40,9 +40,8 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode { }, }) - // Apply stuff seq = append(seq, &EvalOpFilter{ - Ops: []walkOperation{walkValidate, walkRefresh, walkPlan, walkApply}, + Ops: []walkOperation{walkValidate}, Node: &EvalSequence{ Nodes: []EvalNode{ &EvalGetProvider{ @@ -70,6 +69,32 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode { }, }) + // Apply stuff + seq = append(seq, &EvalOpFilter{ + Ops: []walkOperation{walkRefresh, walkPlan, walkApply}, + Node: &EvalSequence{ + Nodes: []EvalNode{ + &EvalGetProvider{ + Name: n, + Output: &provider, + }, + &EvalInterpolate{ + Config: config, + Output: &resourceConfig, + }, + &EvalBuildProviderConfig{ + Provider: n, + Config: &resourceConfig, + Output: &resourceConfig, + }, + &EvalSetProviderConfig{ + Provider: n, + Config: &resourceConfig, + }, + }, + }, + }) + // We configure on everything but validate, since validate may // not have access to all the variables. seq = append(seq, &EvalOpFilter{ diff --git a/terraform/test-fixtures/apply-provider-warning/main.tf b/terraform/test-fixtures/apply-provider-warning/main.tf new file mode 100644 index 000000000..919f140bb --- /dev/null +++ b/terraform/test-fixtures/apply-provider-warning/main.tf @@ -0,0 +1 @@ +resource "aws_instance" "foo" {} From d78052438537635088c5e2899d71f161afc8ca74 Mon Sep 17 00:00:00 2001 From: Kevin Fishner Date: Tue, 28 Jul 2015 16:09:31 -0700 Subject: [PATCH 55/73] update analytics --- website/source/layouts/_footer.erb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/website/source/layouts/_footer.erb b/website/source/layouts/_footer.erb index af1fc6ddf..df095a820 100644 --- a/website/source/layouts/_footer.erb +++ b/website/source/layouts/_footer.erb @@ -32,6 +32,24 @@ ga('send', 'pageview'); + + <%= javascript_include_tag "application" %> From 3080c827d8798d21f71ca0ebdf68bb006735eb0e Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Tue, 28 Jul 2015 18:38:59 -0500 Subject: [PATCH 56/73] scripts: change website_push to push from HEAD so it works properly on release branches --- scripts/website_push.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/website_push.sh b/scripts/website_push.sh index 03017e87a..bccb00e0e 100755 --- a/scripts/website_push.sh +++ b/scripts/website_push.sh @@ -9,4 +9,4 @@ DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )" cd $DIR # Push the subtree (force) -git push heroku `git subtree split --prefix website master`:master --force +git push heroku `git subtree split --prefix website HEAD`:master --force From eda2c935d9f8f13c7ee8848f9680795b8cb29adc Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Wed, 29 Jul 2015 09:34:59 -0500 Subject: [PATCH 57/73] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6720b41d..9a4eb7d61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,8 +21,9 @@ BUG FIXES: * core: Prevent error duplication in `apply` [GH-2815] * provider/aws: Fix issue with toggling monitoring in AWS Instances [GH-2794] * provider/aws: Fix issue with Spot Instance Requests and cancellation [GH-2805] - * provider/aws: Fixx issue when unable to find a Root Block Device name of an Instance Backed + * provider/aws: Fix issue when unable to find a Root Block Device name of an Instance Backed AMI [GH-2646] + * provider/dnsimple: Domain and type should force new records [GH-2777] ## 0.6.1 (July 20, 2015) From 6bfd1db8d4e6f025722e1c6bde84d60c45970618 Mon Sep 17 00:00:00 2001 From: Clint Date: Wed, 29 Jul 2015 09:38:31 -0500 Subject: [PATCH 58/73] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a4eb7d61..d95645313 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ BUG FIXES: * provider/aws: Fix issue when unable to find a Root Block Device name of an Instance Backed AMI [GH-2646] * provider/dnsimple: Domain and type should force new records [GH-2777] + * provider/aws: Fix issue with IAM Server Certificates and Chains [GH-2871] + * provider/aws: Fix issue with IAM Server Certificates when using `path` [GH-2871] ## 0.6.1 (July 20, 2015) From d3b93d54fb76f2bbc86c54de17b284cd1cf60999 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Wed, 29 Jul 2015 11:13:19 -0500 Subject: [PATCH 59/73] use d.Id() --- builtin/providers/aws/resource_aws_elasticache_cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_elasticache_cluster.go b/builtin/providers/aws/resource_aws_elasticache_cluster.go index a1d0db6f1..fa001aa61 100644 --- a/builtin/providers/aws/resource_aws_elasticache_cluster.go +++ b/builtin/providers/aws/resource_aws_elasticache_cluster.go @@ -196,7 +196,7 @@ func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{ stateConf := &resource.StateChangeConf{ Pending: pending, Target: "available", - Refresh: cacheClusterStateRefreshFunc(conn, *resp.CacheCluster.CacheClusterID, "available", pending), + Refresh: cacheClusterStateRefreshFunc(conn, d.Id(), "available", pending), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, From 1f314444f45c3774fc1dbd9490704ed2f8e80dd4 Mon Sep 17 00:00:00 2001 From: Clint Date: Wed, 29 Jul 2015 11:42:39 -0500 Subject: [PATCH 60/73] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d95645313..073815d12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ BUG FIXES: * core: Prevent error duplication in `apply` [GH-2815] * provider/aws: Fix issue with toggling monitoring in AWS Instances [GH-2794] * provider/aws: Fix issue with Spot Instance Requests and cancellation [GH-2805] + * provider/aws: Fix issue with checking for ElastiCache cluster cache node status [GH-2842] * provider/aws: Fix issue when unable to find a Root Block Device name of an Instance Backed AMI [GH-2646] * provider/dnsimple: Domain and type should force new records [GH-2777] From 9416d10ccc40d0beb733ad490b9557f6dacb7227 Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Wed, 29 Jul 2015 14:48:04 -0500 Subject: [PATCH 61/73] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 073815d12..7d3a4f644 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ IMPROVEMENTS: BUG FIXES: * core: Prevent error duplication in `apply` [GH-2815] + * core: Fix crash when a provider validation adds a warning [GH-2878] * provider/aws: Fix issue with toggling monitoring in AWS Instances [GH-2794] * provider/aws: Fix issue with Spot Instance Requests and cancellation [GH-2805] * provider/aws: Fix issue with checking for ElastiCache cluster cache node status [GH-2842] From a8d0a70c0389de763ab77a8778d7c7148b2ace4b Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 23 Jul 2015 16:53:44 -0400 Subject: [PATCH 62/73] providers/google: Add account_file_contents to provider --- builtin/providers/google/config.go | 10 +++++++--- builtin/providers/google/provider.go | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/builtin/providers/google/config.go b/builtin/providers/google/config.go index 6af5fbd61..99e693fd4 100644 --- a/builtin/providers/google/config.go +++ b/builtin/providers/google/config.go @@ -23,9 +23,10 @@ import ( // Config is the configuration structure used to instantiate the Google // provider. type Config struct { - AccountFile string - Project string - Region string + AccountFile string + AccountFileContents string + Project string + Region string clientCompute *compute.Service clientContainer *container.Service @@ -40,6 +41,9 @@ func (c *Config) loadAndValidate() error { if c.AccountFile == "" { c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE") } + if c.AccountFileContents == "" { + c.AccountFileContents = os.Getenv("GOOGLE_ACCOUNT_FILE_CONTENTS") + } if c.Project == "" { c.Project = os.Getenv("GOOGLE_PROJECT") } diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index 30cef8c1b..c93812d5a 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -15,6 +15,12 @@ func Provider() terraform.ResourceProvider { DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil), }, + "account_file_contents": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE_CONTENTS", nil), + }, + "project": &schema.Schema{ Type: schema.TypeString, Required: true, From 4ce776d252c29b26466b81dfd2de1c062f9e94fa Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 23 Jul 2015 17:56:32 -0400 Subject: [PATCH 63/73] providers/google: Use account_file_contents if provided --- builtin/providers/google/config.go | 33 ++++++++---- builtin/providers/google/config_test.go | 67 +++++++++++++++++++------ builtin/providers/google/provider.go | 7 +-- 3 files changed, 80 insertions(+), 27 deletions(-) diff --git a/builtin/providers/google/config.go b/builtin/providers/google/config.go index 99e693fd4..853b5228a 100644 --- a/builtin/providers/google/config.go +++ b/builtin/providers/google/config.go @@ -3,10 +3,12 @@ package google import ( "encoding/json" "fmt" + "io/ioutil" "log" "net/http" "os" "runtime" + "strings" // TODO(dcunnin): Use version code from version.go @@ -54,10 +56,25 @@ func (c *Config) loadAndValidate() error { var client *http.Client if c.AccountFile != "" { - if err := loadJSON(&account, c.AccountFile); err != nil { + if c.AccountFileContents != "" { return fmt.Errorf( - "Error loading account file '%s': %s", - c.AccountFile, + "Cannot provide both account_file and account_file_contents", + ) + } + + b, err := ioutil.ReadFile(c.AccountFile) + if err != nil { + return err + } + + c.AccountFileContents = string(b) + } + + if c.AccountFileContents != "" { + if err := parseJSON(&account, c.AccountFileContents); err != nil { + return fmt.Errorf( + "Error parsing account file contents '%s': %s", + c.AccountFileContents, err) } @@ -150,13 +167,9 @@ type accountFile struct { ClientId string `json:"client_id"` } -func loadJSON(result interface{}, path string) error { - f, err := os.Open(path) - if err != nil { - return err - } - defer f.Close() +func parseJSON(result interface{}, contents string) error { + r := strings.NewReader(contents) + dec := json.NewDecoder(r) - dec := json.NewDecoder(f) return dec.Decode(result) } diff --git a/builtin/providers/google/config_test.go b/builtin/providers/google/config_test.go index b4ee58520..3ec20376a 100644 --- a/builtin/providers/google/config_test.go +++ b/builtin/providers/google/config_test.go @@ -1,24 +1,63 @@ package google import ( - "reflect" + "io/ioutil" "testing" ) -func TestConfigLoadJSON_account(t *testing.T) { - var actual accountFile - if err := loadJSON(&actual, "./test-fixtures/fake_account.json"); err != nil { - t.Fatalf("err: %s", err) +const testFakeAccountFilePath = "./test-fixtures/fake_account.json" + +func TestConfigLoadAndValidate_accountFile(t *testing.T) { + config := Config{ + AccountFile: testFakeAccountFilePath, + Project: "my-gce-project", + Region: "us-central1", } - expected := accountFile{ - PrivateKeyId: "foo", - PrivateKey: "bar", - ClientEmail: "foo@bar.com", - ClientId: "id@foo.com", - } - - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) + err := config.loadAndValidate() + if err != nil { + t.Fatalf("error: %v", err) + } +} + +func TestConfigLoadAndValidate_accountFileContents(t *testing.T) { + contents, err := ioutil.ReadFile(testFakeAccountFilePath) + if err != nil { + t.Fatalf("error: %v", err) + } + config := Config{ + AccountFileContents: string(contents), + Project: "my-gce-project", + Region: "us-central1", + } + + err = config.loadAndValidate() + if err != nil { + t.Fatalf("error: %v", err) + } +} + +func TestConfigLoadAndValidate_none(t *testing.T) { + config := Config{ + Project: "my-gce-project", + Region: "us-central1", + } + + err := config.loadAndValidate() + if err != nil { + t.Fatalf("error: %v", err) + } +} + +func TestConfigLoadAndValidate_both(t *testing.T) { + config := Config{ + AccountFile: testFakeAccountFilePath, + AccountFileContents: "{}", + Project: "my-gce-project", + Region: "us-central1", + } + + if config.loadAndValidate() == nil { + t.Fatalf("expected error, but got nil") } } diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index c93812d5a..969895d17 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -59,9 +59,10 @@ func Provider() terraform.ResourceProvider { func providerConfigure(d *schema.ResourceData) (interface{}, error) { config := Config{ - AccountFile: d.Get("account_file").(string), - Project: d.Get("project").(string), - Region: d.Get("region").(string), + AccountFile: d.Get("account_file").(string), + AccountFileContents: d.Get("account_file_contents").(string), + Project: d.Get("project").(string), + Region: d.Get("region").(string), } if err := config.loadAndValidate(); err != nil { From c7954dbf745baf6fb34ce14cbf90b3b057f510e7 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 24 Jul 2015 10:09:19 -0400 Subject: [PATCH 64/73] providers/google: Document account_file_contents --- .../docs/providers/google/index.html.markdown | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/website/source/docs/providers/google/index.html.markdown b/website/source/docs/providers/google/index.html.markdown index 8adb9ed90..86745b8af 100644 --- a/website/source/docs/providers/google/index.html.markdown +++ b/website/source/docs/providers/google/index.html.markdown @@ -34,13 +34,19 @@ resource "google_compute_instance" "default" { The following keys can be used to configure the provider. -* `account_file` - (Required) Path to the JSON file used to describe your - account credentials, downloaded from Google Cloud Console. More details on - retrieving this file are below. The _account file_ can be "" if you - are running terraform from a GCE instance with a properly-configured [Compute - Engine Service Account](https://cloud.google.com/compute/docs/authentication). - This can also be specified with the `GOOGLE_ACCOUNT_FILE` shell environment - variable. +* `account_file` - (Required, unless `account_file_contents` is present) Path + to the JSON file used to describe your account credentials, downloaded from + Google Cloud Console. More details on retrieving this file are below. The + _account file_ can be "" if you are running terraform from a GCE instance with + a properly-configured [Compute Engine Service + Account](https://cloud.google.com/compute/docs/authentication). This can also + be specified with the `GOOGLE_ACCOUNT_FILE` shell environment variable. + +* `account_file_contents` - (Required, unless `account_file` is present) The + contents of `account_file`. This can be used to pass the account credentials + with a Terraform var or environment variable if the account file is not + accessible. This can also be specified with the `GOOGLE_ACCOUNT_FILE_CONTENTS` + shell environment variable. * `project` - (Required) The ID of the project to apply any resources to. This can also be specified with the `GOOGLE_PROJECT` shell environment variable. From a7ca7e0b36fcfab21d5c678514d62b3c865a0b4a Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 24 Jul 2015 10:20:08 -0400 Subject: [PATCH 65/73] providers/google: Add account_file/account_file_contents ConflictsWith --- builtin/providers/google/provider.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index 969895d17..8d26bc627 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -10,15 +10,17 @@ func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ "account_file": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil), + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"account_file_contents"}, + DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil), }, "account_file_contents": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE_CONTENTS", nil), + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"account_file"}, + DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE_CONTENTS", nil), }, "project": &schema.Schema{ From 2a04708d664ef9b4800cf216577993b0c5af8303 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Fri, 24 Jul 2015 14:25:27 -0400 Subject: [PATCH 66/73] providers/google: Default account_file* to empty Prevents prompting for input --- builtin/providers/google/provider.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index 8d26bc627..c1b2316fd 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -10,17 +10,15 @@ func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ "account_file": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"account_file_contents"}, - DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil), + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", ""), }, "account_file_contents": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"account_file"}, - DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE_CONTENTS", nil), + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE_CONTENTS", ""), }, "project": &schema.Schema{ From 773852e2d5fe7e70afb034c54dfd4f319c479c14 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Mon, 27 Jul 2015 15:35:52 -0400 Subject: [PATCH 67/73] providers/google: Change account_file to JSON If JSON fails to parse, treat it as a file path --- builtin/providers/google/config.go | 50 ++++++++++--------- builtin/providers/google/config_test.go | 31 ++++-------- builtin/providers/google/provider.go | 49 +++++++++++++----- .../docs/providers/google/index.html.markdown | 22 +++----- 4 files changed, 79 insertions(+), 73 deletions(-) diff --git a/builtin/providers/google/config.go b/builtin/providers/google/config.go index 853b5228a..409443fdb 100644 --- a/builtin/providers/google/config.go +++ b/builtin/providers/google/config.go @@ -25,10 +25,9 @@ import ( // Config is the configuration structure used to instantiate the Google // provider. type Config struct { - AccountFile string - AccountFileContents string - Project string - Region string + AccountFile string + Project string + Region string clientCompute *compute.Service clientContainer *container.Service @@ -39,13 +38,9 @@ type Config struct { func (c *Config) loadAndValidate() error { var account accountFile - // TODO: validation that it isn't blank if c.AccountFile == "" { c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE") } - if c.AccountFileContents == "" { - c.AccountFileContents = os.Getenv("GOOGLE_ACCOUNT_FILE_CONTENTS") - } if c.Project == "" { c.Project = os.Getenv("GOOGLE_PROJECT") } @@ -56,25 +51,32 @@ func (c *Config) loadAndValidate() error { var client *http.Client if c.AccountFile != "" { - if c.AccountFileContents != "" { - return fmt.Errorf( - "Cannot provide both account_file and account_file_contents", - ) + contents := c.AccountFile + + // Assume account_file is a JSON string + if err := parseJSON(&account, contents); err != nil { + // If account_file was not JSON, assume it is a file path instead + if _, err := os.Stat(c.AccountFile); os.IsNotExist(err) { + return fmt.Errorf( + "account_file path does not exist: %s", + c.AccountFile) + } + + b, err := ioutil.ReadFile(c.AccountFile) + if err != nil { + return fmt.Errorf( + "Error reading account_file from path '%s': %s", + c.AccountFile, + err) + } + + contents = string(b) } - b, err := ioutil.ReadFile(c.AccountFile) - if err != nil { - return err - } - - c.AccountFileContents = string(b) - } - - if c.AccountFileContents != "" { - if err := parseJSON(&account, c.AccountFileContents); err != nil { + if err := parseJSON(&account, contents); err != nil { return fmt.Errorf( - "Error parsing account file contents '%s': %s", - c.AccountFileContents, + "Error parsing account file '%s': %s", + contents, err) } diff --git a/builtin/providers/google/config_test.go b/builtin/providers/google/config_test.go index 3ec20376a..cc1b6213f 100644 --- a/builtin/providers/google/config_test.go +++ b/builtin/providers/google/config_test.go @@ -7,7 +7,7 @@ import ( const testFakeAccountFilePath = "./test-fixtures/fake_account.json" -func TestConfigLoadAndValidate_accountFile(t *testing.T) { +func TestConfigLoadAndValidate_accountFilePath(t *testing.T) { config := Config{ AccountFile: testFakeAccountFilePath, Project: "my-gce-project", @@ -20,15 +20,15 @@ func TestConfigLoadAndValidate_accountFile(t *testing.T) { } } -func TestConfigLoadAndValidate_accountFileContents(t *testing.T) { +func TestConfigLoadAndValidate_accountFileJSON(t *testing.T) { contents, err := ioutil.ReadFile(testFakeAccountFilePath) if err != nil { t.Fatalf("error: %v", err) } config := Config{ - AccountFileContents: string(contents), - Project: "my-gce-project", - Region: "us-central1", + AccountFile: string(contents), + Project: "my-gce-project", + Region: "us-central1", } err = config.loadAndValidate() @@ -37,24 +37,11 @@ func TestConfigLoadAndValidate_accountFileContents(t *testing.T) { } } -func TestConfigLoadAndValidate_none(t *testing.T) { +func TestConfigLoadAndValidate_accountFileJSONInvalid(t *testing.T) { config := Config{ - Project: "my-gce-project", - Region: "us-central1", - } - - err := config.loadAndValidate() - if err != nil { - t.Fatalf("error: %v", err) - } -} - -func TestConfigLoadAndValidate_both(t *testing.T) { - config := Config{ - AccountFile: testFakeAccountFilePath, - AccountFileContents: "{}", - Project: "my-gce-project", - Region: "us-central1", + AccountFile: "{this is not json}", + Project: "my-gce-project", + Region: "us-central1", } if config.loadAndValidate() == nil { diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index c1b2316fd..b99ac44b3 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -1,6 +1,10 @@ package google import ( + "encoding/json" + "fmt" + "os" + "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" ) @@ -10,15 +14,10 @@ func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ "account_file": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", ""), - }, - - "account_file_contents": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE_CONTENTS", ""), + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil), + ValidateFunc: validateAccountFile, }, "project": &schema.Schema{ @@ -59,10 +58,9 @@ func Provider() terraform.ResourceProvider { func providerConfigure(d *schema.ResourceData) (interface{}, error) { config := Config{ - AccountFile: d.Get("account_file").(string), - AccountFileContents: d.Get("account_file_contents").(string), - Project: d.Get("project").(string), - Region: d.Get("region").(string), + AccountFile: d.Get("account_file").(string), + Project: d.Get("project").(string), + Region: d.Get("region").(string), } if err := config.loadAndValidate(); err != nil { @@ -71,3 +69,28 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { return &config, nil } + +func validateAccountFile(v interface{}, k string) (warnings []string, errors []error) { + value := v.(string) + + if value == "" { + return + } + + var account accountFile + if err := json.Unmarshal([]byte(value), &account); err != nil { + warnings = append(warnings, ` +account_file is not valid JSON, so we are assuming it is a file path. This +support will be removed in the future. Please update your configuration to use +${file("filename.json")} instead.`) + + return + } + + if _, err := os.Stat(value); os.IsNotExist(err) { + errors = append(errors, err) + fmt.Errorf("account_file path does not exist: %s", value) + } + + return +} diff --git a/website/source/docs/providers/google/index.html.markdown b/website/source/docs/providers/google/index.html.markdown index 86745b8af..3bbef84c6 100644 --- a/website/source/docs/providers/google/index.html.markdown +++ b/website/source/docs/providers/google/index.html.markdown @@ -19,7 +19,7 @@ Use the navigation to the left to read about the available resources. ``` # Configure the Google Cloud provider provider "google" { - account_file = "account.json" + account_file = "${file("account.json")}" project = "my-gce-project" region = "us-central1" } @@ -34,19 +34,13 @@ resource "google_compute_instance" "default" { The following keys can be used to configure the provider. -* `account_file` - (Required, unless `account_file_contents` is present) Path - to the JSON file used to describe your account credentials, downloaded from - Google Cloud Console. More details on retrieving this file are below. The - _account file_ can be "" if you are running terraform from a GCE instance with - a properly-configured [Compute Engine Service - Account](https://cloud.google.com/compute/docs/authentication). This can also - be specified with the `GOOGLE_ACCOUNT_FILE` shell environment variable. - -* `account_file_contents` - (Required, unless `account_file` is present) The - contents of `account_file`. This can be used to pass the account credentials - with a Terraform var or environment variable if the account file is not - accessible. This can also be specified with the `GOOGLE_ACCOUNT_FILE_CONTENTS` - shell environment variable. +* `account_file` - (Required) Contents of the JSON file used to describe your + account credentials, downloaded from Google Cloud Console. More details on + retrieving this file are below. The `account file` can be "" if you are running + terraform from a GCE instance with a properly-configured [Compute Engine + Service Account](https://cloud.google.com/compute/docs/authentication). This + can also be specified with the `GOOGLE_ACCOUNT_FILE` shell environment + variable. * `project` - (Required) The ID of the project to apply any resources to. This can also be specified with the `GOOGLE_PROJECT` shell environment variable. From 8faa11115625d024400d27b16616d108906ea69a Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Mon, 27 Jul 2015 17:06:48 -0400 Subject: [PATCH 68/73] providers/google: Return if we could parse JSON --- builtin/providers/google/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index b99ac44b3..af5ae03ce 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -83,7 +83,7 @@ func validateAccountFile(v interface{}, k string) (warnings []string, errors []e account_file is not valid JSON, so we are assuming it is a file path. This support will be removed in the future. Please update your configuration to use ${file("filename.json")} instead.`) - + } else { return } From 4764a556c0258322acf4bd396198d0eb0d2f64bb Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Mon, 27 Jul 2015 17:07:38 -0400 Subject: [PATCH 69/73] providers/google: Fix error appending --- builtin/providers/google/provider.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index af5ae03ce..6dade8dea 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -87,9 +87,12 @@ ${file("filename.json")} instead.`) return } - if _, err := os.Stat(value); os.IsNotExist(err) { - errors = append(errors, err) - fmt.Errorf("account_file path does not exist: %s", value) + if _, err := os.Stat(value); err != nil { + errors = append(errors, + fmt.Errorf( + "account_file path could not be read from '%s': %s", + value, + err)) } return From 7884456c4b8352bd5fa786f230002c4c1a3c5ae4 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Tue, 28 Jul 2015 09:36:05 -0400 Subject: [PATCH 70/73] providers/google: Fix reading account_file path --- builtin/providers/google/config.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/builtin/providers/google/config.go b/builtin/providers/google/config.go index 409443fdb..838966528 100644 --- a/builtin/providers/google/config.go +++ b/builtin/providers/google/config.go @@ -71,13 +71,13 @@ func (c *Config) loadAndValidate() error { } contents = string(b) - } - if err := parseJSON(&account, contents); err != nil { - return fmt.Errorf( - "Error parsing account file '%s': %s", - contents, - err) + if err := parseJSON(&account, contents); err != nil { + return fmt.Errorf( + "Error parsing account file '%s': %s", + contents, + err) + } } clientScopes := []string{ From bbba052e8f7475f8ce19adc3450967e795d6c312 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Thu, 30 Jul 2015 09:12:36 -0400 Subject: [PATCH 71/73] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d3a4f644..7141ecd05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ IMPROVEMENTS: * provider/aws: Added `source_dest_check` attribute to the aws_network_interface [GH-2741] * provider/aws: Clean up externally removed Launch Configurations [GH-2806] * provider/aws: Compute private ip addresses of ENIs if they are not specified [GH-2743] + * provider/google: `account_file` is now expected to be JSON. Paths are still supported for + backwards compatibility. [GH-2839] BUG FIXES: From 488587467cdfb38a139f6266496f7090e00ac90a Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Thu, 30 Jul 2015 09:27:13 -0500 Subject: [PATCH 72/73] code formatting --- builtin/providers/azure/resource_azure_instance.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/builtin/providers/azure/resource_azure_instance.go b/builtin/providers/azure/resource_azure_instance.go index 5ade3b55d..cf20e8218 100644 --- a/builtin/providers/azure/resource_azure_instance.go +++ b/builtin/providers/azure/resource_azure_instance.go @@ -650,8 +650,7 @@ func retrieveOSImageDetails( } if img.MediaLink == "" { if storage == "" { - return nil, "", nil, - PlatformStorageError + return nil, "", nil, PlatformStorageError } img.MediaLink = fmt.Sprintf(osDiskBlobStorageURL, storage, name) } From 9c8ae86db5dccf9da36e708a965694bb5f56813a Mon Sep 17 00:00:00 2001 From: Clint Date: Thu, 30 Jul 2015 09:29:19 -0500 Subject: [PATCH 73/73] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7141ecd05..7fc863890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ IMPROVEMENTS: * provider/aws: Added `source_dest_check` attribute to the aws_network_interface [GH-2741] * provider/aws: Clean up externally removed Launch Configurations [GH-2806] * provider/aws: Compute private ip addresses of ENIs if they are not specified [GH-2743] + * provider/azure: Provide a simpler error when using a Platform Image without a + Storage Service [GH-2861] * provider/google: `account_file` is now expected to be JSON. Paths are still supported for backwards compatibility. [GH-2839]