Merge branch 'master' into time-asg-tags-support

* master:
  update CHANGELOG
  providers/digitalocean: add dot in GET response
  providers/digitalocean: force fqdn in dns rr value
  update CHANGELOG
  Add disk size to google_compute_instance disk blocks.
  'project' should be set to the project's ID, not its name.
  Don't error when enabling DNS hostnames in a VPC
  Correct AWS VPC or route table read functions
  Updates to GCE Instances and Instance Templates to allow for false values to be set for the auto_delete setting.
  Update GCE Instance Template tests now that existing disk must exist prior to template creation.
  Update Google API import to point to the new location.
  add network field to the network_interface
This commit is contained in:
Clint Shryock 2015-03-26 13:47:46 -05:00
commit 877eb902a0
28 changed files with 218 additions and 50 deletions

View File

@ -40,6 +40,7 @@ IMPROVEMENTS:
like refresh.
* core: Autoload `terraform.tfvars.json` as well as `terraform.tfvars` [GH-1030]
* core: `.tf` files that start with a period are now ignored. [GH-1227]
* providers/google: Add `size` option to disk blocks for instances. [GH-1284]
BUG FIXES:
@ -58,6 +59,8 @@ BUG FIXES:
* providers/aws: Longer wait times for route53 records (30 mins). [GH-1164]
* providers/digitalocean: Waits until droplet is ready to be destroyed [GH-1057]
* providers/digitalocean: More lenient about 404's while waiting [GH-1062]
* providers/digitalocean: FQDN for domain records in CNAME, MX, NS, etc.
Also fixes invalid updates in plans. [GH-863]
* providers/google: Network data in state was not being stored. [GH-1095]
PLUGIN CHANGES:

View File

@ -107,6 +107,7 @@ func resourceAwsRouteTableRead(d *schema.ResourceData, meta interface{}) error {
return err
}
if rtRaw == nil {
d.SetId("")
return nil
}

View File

@ -195,13 +195,13 @@ func resourceAwsVpcUpdate(d *schema.ResourceData, meta interface{}) error {
}
log.Printf(
"[INFO] Modifying enable_dns_hostnames vpc attribute for %s: %#v",
"[INFO] Modifying enable_dns_support vpc attribute for %s: %#v",
d.Id(), modifyOpts)
if err := ec2conn.ModifyVPCAttribute(modifyOpts); err != nil {
return err
}
d.SetPartial("enable_dns_hostnames")
d.SetPartial("enable_dns_support")
}
if d.HasChange("enable_dns_support") {
@ -241,7 +241,7 @@ func resourceAwsVpcDelete(d *schema.ResourceData, meta interface{}) error {
}
log.Printf("[INFO] Deleting VPC: %s", d.Id())
if err := ec2conn.DeleteVPC(DeleteVpcOpts); err != nil {
ec2err, ok := err.(*aws.APIError)
ec2err, ok := err.(aws.APIError)
if ok && ec2err.Code == "InvalidVpcID.NotFound" {
return nil
}
@ -261,7 +261,7 @@ func VPCStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc {
}
resp, err := conn.DescribeVPCs(DescribeVpcOpts)
if err != nil {
if ec2err, ok := err.(*aws.APIError); ok && ec2err.Code == "InvalidVpcID.NotFound" {
if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "InvalidVpcID.NotFound" {
resp = nil
} else {
log.Printf("Error on VPCStateRefresh: %s", err)

View File

@ -133,7 +133,7 @@ func testAccCheckVpcDestroy(s *terraform.State) error {
}
// Verify the error is what we want
ec2err, ok := err.(*aws.APIError)
ec2err, ok := err.(aws.APIError)
if !ok {
return err
}

View File

@ -91,8 +91,9 @@ func resourceDigitalOceanRecordCreate(d *schema.ResourceData, meta interface{})
func resourceDigitalOceanRecordRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*digitalocean.Client)
domain := d.Get("domain").(string)
rec, err := client.RetrieveRecord(d.Get("domain").(string), d.Id())
rec, err := client.RetrieveRecord(domain, d.Id())
if err != nil {
// If the record is somehow already destroyed, mark as
// succesfully gone
@ -104,6 +105,18 @@ func resourceDigitalOceanRecordRead(d *schema.ResourceData, meta interface{}) er
return err
}
// Update response data for records with domain value
if t := rec.Type; t == "CNAME" || t == "MX" || t == "NS" || t == "SRV" {
// Append dot to response if resource value is absolute
if value := d.Get("value").(string); strings.HasSuffix(value, ".") {
rec.Data += "."
// If resource value ends with current domain, make response data absolute
if strings.HasSuffix(value, domain+".") {
rec.Data += domain + "."
}
}
}
d.Set("name", rec.Name)
d.Set("type", rec.Type)
d.Set("value", rec.Data)

View File

@ -76,6 +76,87 @@ func TestAccDigitalOceanRecord_Updated(t *testing.T) {
})
}
func TestAccDigitalOceanRecord_HostnameValue(t *testing.T) {
var record digitalocean.Record
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDigitalOceanRecordDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckDigitalOceanRecordConfig_cname,
Check: resource.ComposeTestCheckFunc(
testAccCheckDigitalOceanRecordExists("digitalocean_record.foobar", &record),
testAccCheckDigitalOceanRecordAttributesHostname("a", &record),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "name", "terraform"),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "domain", "foobar-test-terraform.com"),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "value", "a.foobar-test-terraform.com."),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "type", "CNAME"),
),
},
},
})
}
func TestAccDigitalOceanRecord_RelativeHostnameValue(t *testing.T) {
var record digitalocean.Record
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDigitalOceanRecordDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckDigitalOceanRecordConfig_relative_cname,
Check: resource.ComposeTestCheckFunc(
testAccCheckDigitalOceanRecordExists("digitalocean_record.foobar", &record),
testAccCheckDigitalOceanRecordAttributesHostname("a.b", &record),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "name", "terraform"),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "domain", "foobar-test-terraform.com"),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "value", "a.b"),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "type", "CNAME"),
),
},
},
})
}
func TestAccDigitalOceanRecord_ExternalHostnameValue(t *testing.T) {
var record digitalocean.Record
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDigitalOceanRecordDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckDigitalOceanRecordConfig_external_cname,
Check: resource.ComposeTestCheckFunc(
testAccCheckDigitalOceanRecordExists("digitalocean_record.foobar", &record),
testAccCheckDigitalOceanRecordAttributesHostname("a.foobar-test-terraform.net", &record),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "name", "terraform"),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "domain", "foobar-test-terraform.com"),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "value", "a.foobar-test-terraform.net."),
resource.TestCheckResourceAttr(
"digitalocean_record.foobar", "type", "CNAME"),
),
},
},
})
}
func testAccCheckDigitalOceanRecordDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*digitalocean.Client)
@ -146,6 +227,17 @@ func testAccCheckDigitalOceanRecordExists(n string, record *digitalocean.Record)
}
}
func testAccCheckDigitalOceanRecordAttributesHostname(data string, record *digitalocean.Record) resource.TestCheckFunc {
return func(s *terraform.State) error {
if record.Data != data {
return fmt.Errorf("Bad value: expected %s, got %s", data, record.Data)
}
return nil
}
}
const testAccCheckDigitalOceanRecordConfig_basic = `
resource "digitalocean_domain" "foobar" {
name = "foobar-test-terraform.com"
@ -173,3 +265,45 @@ resource "digitalocean_record" "foobar" {
value = "192.168.0.11"
type = "A"
}`
const testAccCheckDigitalOceanRecordConfig_cname = `
resource "digitalocean_domain" "foobar" {
name = "foobar-test-terraform.com"
ip_address = "192.168.0.10"
}
resource "digitalocean_record" "foobar" {
domain = "${digitalocean_domain.foobar.name}"
name = "terraform"
value = "a.foobar-test-terraform.com."
type = "CNAME"
}`
const testAccCheckDigitalOceanRecordConfig_relative_cname = `
resource "digitalocean_domain" "foobar" {
name = "foobar-test-terraform.com"
ip_address = "192.168.0.10"
}
resource "digitalocean_record" "foobar" {
domain = "${digitalocean_domain.foobar.name}"
name = "terraform"
value = "a.b"
type = "CNAME"
}`
const testAccCheckDigitalOceanRecordConfig_external_cname = `
resource "digitalocean_domain" "foobar" {
name = "foobar-test-terraform.com"
ip_address = "192.168.0.10"
}
resource "digitalocean_record" "foobar" {
domain = "${digitalocean_domain.foobar.name}"
name = "terraform"
value = "a.foobar-test-terraform.net."
type = "CNAME"
}`

View File

@ -7,11 +7,10 @@ import (
"net/http"
"os"
"code.google.com/p/google-api-go-client/compute/v1"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/jwt"
"google.golang.org/api/compute/v1"
)
// Config is the configuration structure used to instantiate the Google

View File

@ -1,7 +1,7 @@
package google
import (
"code.google.com/p/google-api-go-client/compute/v1"
"google.golang.org/api/compute/v1"
)
// readDiskType finds the disk type with the given name.

View File

@ -4,7 +4,8 @@ import (
"bytes"
"fmt"
"code.google.com/p/google-api-go-client/compute/v1"
"google.golang.org/api/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
)

View File

@ -5,9 +5,9 @@ import (
"log"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeAddress() *schema.Resource {

View File

@ -4,9 +4,9 @@ import (
"fmt"
"testing"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/compute/v1"
)
func TestAccComputeAddress_basic(t *testing.T) {

View File

@ -5,9 +5,9 @@ import (
"log"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeDisk() *schema.Resource {

View File

@ -4,9 +4,9 @@ import (
"fmt"
"testing"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/compute/v1"
)
func TestAccComputeDisk_basic(t *testing.T) {

View File

@ -6,10 +6,10 @@ import (
"sort"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeFirewall() *schema.Resource {

View File

@ -4,9 +4,9 @@ import (
"fmt"
"testing"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/compute/v1"
)
func TestAccComputeFirewall_basic(t *testing.T) {

View File

@ -5,9 +5,9 @@ import (
"log"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeForwardingRule() *schema.Resource {

View File

@ -5,9 +5,9 @@ import (
"log"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeHttpHealthCheck() *schema.Resource {

View File

@ -5,10 +5,10 @@ import (
"log"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeInstance() *schema.Resource {
@ -72,6 +72,13 @@ func resourceComputeInstance() *schema.Resource {
"auto_delete": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: true,
ForceNew: true,
},
"size": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
},
@ -283,11 +290,7 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err
disk.Type = "PERSISTENT"
disk.Mode = "READ_WRITE"
disk.Boot = i == 0
disk.AutoDelete = true
if v, ok := d.GetOk(prefix + ".auto_delete"); ok {
disk.AutoDelete = v.(bool)
}
disk.AutoDelete = d.Get(prefix + ".auto_delete").(bool)
// Load up the disk for this disk if specified
if v, ok := d.GetOk(prefix + ".disk"); ok {
@ -331,6 +334,11 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err
disk.InitializeParams.DiskType = diskType.SelfLink
}
if v, ok := d.GetOk(prefix + ".size"); ok {
diskSizeGb := v.(int)
disk.InitializeParams.DiskSizeGb = int64(diskSizeGb)
}
disks = append(disks, &disk)
}
@ -564,6 +572,7 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
networkInterfaces = append(networkInterfaces, map[string]interface{}{
"name": iface.Name,
"address": iface.NetworkIP,
"network": iface.Network,
"access_config": accessConfigs,
})
}

View File

@ -4,10 +4,10 @@ import (
"fmt"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeInstanceTemplate() *schema.Resource {
@ -58,6 +58,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
"auto_delete": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: true,
ForceNew: true,
},
@ -235,11 +236,7 @@ func buildDisks(d *schema.ResourceData, meta interface{}) []*compute.AttachedDis
disk.Mode = "READ_WRITE"
disk.Interface = "SCSI"
disk.Boot = i == 0
disk.AutoDelete = true
if v, ok := d.GetOk(prefix + ".auto_delete"); ok {
disk.AutoDelete = v.(bool)
}
disk.AutoDelete = d.Get(prefix + ".auto_delete").(bool)
if v, ok := d.GetOk(prefix + ".boot"); ok {
disk.Boot = v.(bool)

View File

@ -4,9 +4,9 @@ import (
"fmt"
"testing"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/compute/v1"
)
func TestAccComputeInstanceTemplate_basic(t *testing.T) {
@ -65,7 +65,7 @@ func TestAccComputeInstanceTemplate_disks(t *testing.T) {
testAccCheckComputeInstanceTemplateExists(
"google_compute_instance_template.foobar", &instanceTemplate),
testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true),
testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "foo_existing_disk", false, false),
testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "terraform-test-foobar", false, false),
),
},
},
@ -252,6 +252,14 @@ resource "google_compute_instance_template" "foobar" {
}`
const testAccComputeInstanceTemplate_disks = `
resource "google_compute_disk" "foobar" {
name = "terraform-test-foobar"
image = "debian-7-wheezy-v20140814"
size = 10
type = "pd-ssd"
zone = "us-central1-a"
}
resource "google_compute_instance_template" "foobar" {
name = "terraform-test"
machine_type = "n1-standard-1"
@ -263,7 +271,7 @@ resource "google_compute_instance_template" "foobar" {
}
disk {
source = "foo_existing_disk"
source = "terraform-test-foobar"
auto_delete = false
boot = false
}

View File

@ -5,9 +5,9 @@ import (
"strings"
"testing"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/compute/v1"
)
func TestAccComputeInstance_basic_deprecated_network(t *testing.T) {

View File

@ -5,9 +5,9 @@ import (
"log"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeNetwork() *schema.Resource {

View File

@ -4,9 +4,9 @@ import (
"fmt"
"testing"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/compute/v1"
)
func TestAccComputeNetwork_basic(t *testing.T) {

View File

@ -5,10 +5,10 @@ import (
"log"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeRoute() *schema.Resource {

View File

@ -4,9 +4,9 @@ import (
"fmt"
"testing"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/compute/v1"
)
func TestAccComputeRoute_basic(t *testing.T) {

View File

@ -6,9 +6,9 @@ import (
"strings"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"code.google.com/p/google-api-go-client/googleapi"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeTargetPool() *schema.Resource {

View File

@ -40,7 +40,7 @@ The following keys can be used to configure the provider.
are running terraform from a GCE instance with a properly-configured [Compute
Engine Service Account](https://cloud.google.com/compute/docs/authentication).
* `project` - (Required) The name of the project to apply any resources to.
* `project` - (Required) The ID of the project to apply any resources to.
* `region` - (Required) The region to operate under.

View File

@ -93,6 +93,9 @@ The `disk` block supports:
* `type` - (Optional) The GCE disk type.
* `size` - (Optional) The size of the image in gigabytes. If not specified,
it will inherit the size of its base image.
The `network_interface` block supports:
* `network` - (Required) The name of the network to attach this interface to.