Allow setting boot and attached disk sources by name or self link (#605)

* disk cleanup

* fix attached disk test

* allow disk sources from name or url

* parse disk source better on read

* update docs

* fix boot disk source url
This commit is contained in:
Dana Hoffman 2017-10-23 13:26:59 -07:00 committed by GitHub
parent be0525885e
commit c577ad6e8d
4 changed files with 141 additions and 19 deletions

View File

@ -25,6 +25,10 @@ func ParseSslCertificateFieldValue(sslCertificate string, d TerraformResourceDat
return parseGlobalFieldValue("sslCertificates", sslCertificate, "project", d, config, false)
}
func ParseDiskFieldValue(disk string, d TerraformResourceData, config *Config) (*ZonalFieldValue, error) {
return parseZonalFieldValue("disks", disk, "project", "zone", d, config, false)
}
// ------------------------------------------------------------
// Base helpers used to create helpers for specific fields.
// ------------------------------------------------------------

View File

@ -108,11 +108,12 @@ func resourceComputeInstance() *schema.Resource {
},
"source": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"boot_disk.initialize_params"},
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"boot_disk.initialize_params"},
DiffSuppressFunc: linkDiffSuppress,
},
},
},
@ -207,8 +208,9 @@ func resourceComputeInstance() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"source": &schema.Schema{
Type: schema.TypeString,
Required: true,
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: linkDiffSuppress,
},
"device_name": &schema.Schema{
@ -622,8 +624,12 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err
for i := 0; i < attachedDisksCount; i++ {
prefix := fmt.Sprintf("attached_disk.%d", i)
source, err := ParseDiskFieldValue(d.Get(prefix+".source").(string), d, config)
if err != nil {
return err
}
disk := computeBeta.AttachedDisk{
Source: d.Get(prefix + ".source").(string),
Source: source.RelativeLink(),
AutoDelete: false, // Don't allow autodelete; let terraform handle disk deletion
}
@ -914,7 +920,11 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
attachedDisksCount := d.Get("attached_disk.#").(int)
attachedDiskSources := make(map[string]int, attachedDisksCount)
for i := 0; i < attachedDisksCount; i++ {
attachedDiskSources[d.Get(fmt.Sprintf("attached_disk.%d.source", i)).(string)] = i
source, err := ParseDiskFieldValue(d.Get(fmt.Sprintf("attached_disk.%d.source", i)).(string), d, config)
if err != nil {
return err
}
attachedDiskSources[source.RelativeLink()] = i
}
sIndex := 0
@ -928,7 +938,11 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
scratchDisks = append(scratchDisks, flattenScratchDisk(disk))
sIndex++
} else {
adIndex, inConfig := attachedDiskSources[disk.Source]
source, err := ParseDiskFieldValue(disk.Source, d, config)
if err != nil {
return err
}
adIndex, inConfig := attachedDiskSources[source.RelativeLink()]
di := map[string]interface{}{
"source": disk.Source,
"device_name": disk.DeviceName,
@ -1282,13 +1296,11 @@ func expandBootDisk(d *schema.ResourceData, config *Config, zone *compute.Zone,
}
if v, ok := d.GetOk("boot_disk.0.source"); ok {
diskName := v.(string)
diskData, err := config.clientCompute.Disks.Get(
project, zone.Name, diskName).Do()
source, err := ParseDiskFieldValue(v.(string), d, config)
if err != nil {
return nil, fmt.Errorf("Error loading disk '%s': %s", diskName, err)
return nil, err
}
disk.Source = diskData.SelfLink
disk.Source = source.RelativeLink()
}
if _, ok := d.GetOk("boot_disk.0.initialize_params"); ok {
@ -1322,11 +1334,10 @@ func expandBootDisk(d *schema.ResourceData, config *Config, zone *compute.Zone,
}
func flattenBootDisk(d *schema.ResourceData, disk *computeBeta.AttachedDisk) []map[string]interface{} {
sourceUrl := strings.Split(disk.Source, "/")
result := map[string]interface{}{
"auto_delete": disk.AutoDelete,
"device_name": disk.DeviceName,
"source": sourceUrl[len(sourceUrl)-1],
"source": disk.Source,
// disk_encryption_key_raw is not returned from the API, so copy it from what the user
// originally specified to avoid diffs.
"disk_encryption_key_raw": d.Get("boot_disk.0.disk_encryption_key_raw"),

View File

@ -251,6 +251,30 @@ func TestAccComputeInstance_attachedDisk(t *testing.T) {
})
}
func TestAccComputeInstance_attachedDisk_sourceUrl(t *testing.T) {
t.Parallel()
var instance compute.Instance
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
var diskName = fmt.Sprintf("instance-testd-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeInstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeInstance_attachedDisk_sourceUrl(diskName, instanceName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists(
"google_compute_instance.foobar", &instance),
testAccCheckComputeInstanceDisk(&instance, diskName, false, false),
),
},
},
})
}
func TestAccComputeInstance_bootDisk_source(t *testing.T) {
t.Parallel()
@ -275,6 +299,30 @@ func TestAccComputeInstance_bootDisk_source(t *testing.T) {
})
}
func TestAccComputeInstance_bootDisk_sourceUrl(t *testing.T) {
t.Parallel()
var instance compute.Instance
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
var diskName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeInstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeInstance_bootDisk_sourceUrl(diskName, instanceName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists(
"google_compute_instance.foobar", &instance),
testAccCheckComputeInstanceBootDisk(&instance, diskName),
),
},
},
})
}
func TestAccComputeInstance_bootDisk_type(t *testing.T) {
t.Parallel()
@ -1539,6 +1587,41 @@ resource "google_compute_disk" "foobar" {
zone = "us-central1-a"
}
resource "google_compute_instance" "foobar" {
name = "%s"
machine_type = "n1-standard-1"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-8-jessie-v20160803"
}
}
attached_disk {
source = "${google_compute_disk.foobar.name}"
}
network_interface {
network = "default"
}
metadata {
foo = "bar"
}
}
`, disk, instance)
}
func testAccComputeInstance_attachedDisk_sourceUrl(disk, instance string) string {
return fmt.Sprintf(`
resource "google_compute_disk" "foobar" {
name = "%s"
size = 10
type = "pd-ssd"
zone = "us-central1-a"
}
resource "google_compute_instance" "foobar" {
name = "%s"
machine_type = "n1-standard-1"
@ -1589,6 +1672,30 @@ resource "google_compute_instance" "foobar" {
`, disk, instance)
}
func testAccComputeInstance_bootDisk_sourceUrl(disk, instance string) string {
return fmt.Sprintf(`
resource "google_compute_disk" "foobar" {
name = "%s"
zone = "us-central1-a"
image = "debian-8-jessie-v20160803"
}
resource "google_compute_instance" "foobar" {
name = "%s"
machine_type = "n1-standard-1"
zone = "us-central1-a"
boot_disk {
source = "${google_compute_disk.foobar.self_link}"
}
network_interface {
network = "default"
}
}
`, disk, instance)
}
func testAccComputeInstance_bootDisk_type(instance string, diskType string) string {
return fmt.Sprintf(`
resource "google_compute_instance" "foobar" {

View File

@ -130,7 +130,7 @@ The `boot_disk` block supports:
alongside the new instance. Either `initialize_params` or `source` must be set.
Structure is documented below.
* `source` - (Optional) The name of the existing disk (such as those managed by
* `source` - (Optional) The name or self_link of the existing disk (such as those managed by
`google_compute_disk`) to attach.
The `initialize_params` block supports:
@ -153,7 +153,7 @@ The `scratch_disk` block supports:
The `attached_disk` block supports:
* `source` - (Required) The self_link of the disk to attach to this instance.
* `source` - (Required) The name or self_link of the disk to attach to this instance.
* `device_name` - (Optional) Name with which the attached disk will be accessible
under `/dev/disk/by-id/`