From efe9b53a05820f362413c6c5e3f46679ddd31add Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 25 Aug 2014 16:23:28 -0700 Subject: [PATCH] providers/google: compute_disk --- builtin/providers/google/provider.go | 1 + .../providers/google/resource_compute_disk.go | 134 ++++++++++++++++++ .../google/resource_compute_disk_test.go | 84 +++++++++++ .../google/resource_compute_instance.go | 19 ++- 4 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 builtin/providers/google/resource_compute_disk.go create mode 100644 builtin/providers/google/resource_compute_disk_test.go diff --git a/builtin/providers/google/provider.go b/builtin/providers/google/provider.go index 84e6c17ea..76cc8cb4e 100644 --- a/builtin/providers/google/provider.go +++ b/builtin/providers/google/provider.go @@ -31,6 +31,7 @@ func Provider() *schema.Provider { ResourcesMap: map[string]*schema.Resource{ "google_compute_address": resourceComputeAddress(), + "google_compute_disk": resourceComputeDisk(), "google_compute_instance": resourceComputeInstance(), }, diff --git a/builtin/providers/google/resource_compute_disk.go b/builtin/providers/google/resource_compute_disk.go new file mode 100644 index 000000000..9a7013f2a --- /dev/null +++ b/builtin/providers/google/resource_compute_disk.go @@ -0,0 +1,134 @@ +package google + +import ( + "fmt" + "log" + "time" + + "code.google.com/p/google-api-go-client/compute/v1" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceComputeDisk() *schema.Resource { + return &schema.Resource{ + Create: resourceComputeDiskCreate, + Read: resourceComputeDiskRead, + Delete: resourceComputeDiskDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "zone": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "image": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "size": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func resourceComputeDiskCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + // Build the disk parameter + disk := &compute.Disk{ + Name: d.Get("name").(string), + SizeGb: int64(d.Get("size").(int)), + } + + // If we were given a source image, load that. + if v, ok := d.GetOk("image"); ok { + log.Printf("[DEBUG] Loading image: %s", v.(string)) + image, err := readImage(config, v.(string)) + if err != nil { + return fmt.Errorf( + "Error loading image '%s': %s", + v.(string), err) + } + + disk.SourceImage = image.SelfLink + } + + op, err := config.clientCompute.Disks.Insert( + config.Project, d.Get("zone").(string), disk).Do() + if err != nil { + return fmt.Errorf("Error creating disk: %s", err) + } + + // It probably maybe worked, so store the ID now + d.SetId(disk.Name) + + // Wait for the operation to complete + w := &OperationWaiter{ + Service: config.clientCompute, + Op: op, + Project: config.Project, + Zone: d.Get("zone").(string), + Type: OperationWaitZone, + } + state := w.Conf() + state.Timeout = 2 * time.Minute + state.MinTimeout = 1 * time.Second + if _, err := state.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for address to create: %s", err) + } + + return resourceComputeDiskRead(d, meta) +} + +func resourceComputeDiskRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + _, err := config.clientCompute.Disks.Get( + config.Project, d.Get("zone").(string), d.Id()).Do() + if err != nil { + return fmt.Errorf("Error reading disk: %s", err) + } + + return nil +} + +func resourceComputeDiskDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + // Delete the address + op, err := config.clientCompute.Disks.Delete( + config.Project, d.Get("zone").(string), d.Id()).Do() + if err != nil { + return fmt.Errorf("Error deleting disk: %s", err) + } + + // Wait for the operation to complete + w := &OperationWaiter{ + Service: config.clientCompute, + Op: op, + Project: config.Project, + Zone: d.Get("zone").(string), + Type: OperationWaitZone, + } + state := w.Conf() + state.Timeout = 2 * time.Minute + state.MinTimeout = 1 * time.Second + if _, err := state.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for address to delete: %s", err) + } + + d.SetId("") + return nil +} diff --git a/builtin/providers/google/resource_compute_disk_test.go b/builtin/providers/google/resource_compute_disk_test.go new file mode 100644 index 000000000..188741fa6 --- /dev/null +++ b/builtin/providers/google/resource_compute_disk_test.go @@ -0,0 +1,84 @@ +package google + +import ( + "fmt" + "testing" + + "code.google.com/p/google-api-go-client/compute/v1" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccComputeDisk_basic(t *testing.T) { + var disk compute.Disk + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeDiskDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeDisk_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeDiskExists( + "google_compute_disk.foobar", &disk), + ), + }, + }, + }) +} + +func testAccCheckComputeDiskDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + + for _, rs := range s.Resources { + if rs.Type != "google_compute_disk" { + continue + } + + _, err := config.clientCompute.Disks.Get( + config.Project, rs.Attributes["zone"], rs.ID).Do() + if err == nil { + return fmt.Errorf("Disk still exists") + } + } + + return nil +} + +func testAccCheckComputeDiskExists(n string, disk *compute.Disk) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + + found, err := config.clientCompute.Disks.Get( + config.Project, rs.Attributes["zone"], rs.ID).Do() + if err != nil { + return err + } + + if found.Name != rs.ID { + return fmt.Errorf("Disk not found") + } + + *disk = *found + + return nil + } +} + +const testAccComputeDisk_basic = ` +resource "google_compute_disk" "foobar" { + name = "terraform-test" + image = "debian-7-wheezy-v20140814" + size = 50 + zone = "us-central1-a" +}` diff --git a/builtin/providers/google/resource_compute_instance.go b/builtin/providers/google/resource_compute_instance.go index 2f478f4be..a21263672 100644 --- a/builtin/providers/google/resource_compute_instance.go +++ b/builtin/providers/google/resource_compute_instance.go @@ -70,6 +70,16 @@ func resourceComputeInstance() *schema.Resource { Type: schema.TypeString, Optional: true, }, + + "name": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "internal_address": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, }, }, }, @@ -253,12 +263,19 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - _, err := config.clientCompute.Instances.Get( + instance, err := config.clientCompute.Instances.Get( config.Project, d.Get("zone").(string), d.Id()).Do() if err != nil { return fmt.Errorf("Error reading instance: %s", err) } + // Set the networks + for i, iface := range instance.NetworkInterfaces { + prefix := fmt.Sprintf("network.%d", i) + d.Set(prefix+".name", iface.Name) + d.Set(prefix+".internal_address", iface.NetworkIP) + } + return nil }