github.com/anuaimi/terraform@v0.6.4-0.20150904235404-2bf9aec61da8/builtin/providers/google/resource_compute_disk.go (about)

     1  package google
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  	"google.golang.org/api/compute/v1"
    10  	"google.golang.org/api/googleapi"
    11  )
    12  
    13  func resourceComputeDisk() *schema.Resource {
    14  	return &schema.Resource{
    15  		Create: resourceComputeDiskCreate,
    16  		Read:   resourceComputeDiskRead,
    17  		Delete: resourceComputeDiskDelete,
    18  
    19  		Schema: map[string]*schema.Schema{
    20  			"name": &schema.Schema{
    21  				Type:     schema.TypeString,
    22  				Required: true,
    23  				ForceNew: true,
    24  			},
    25  
    26  			"zone": &schema.Schema{
    27  				Type:     schema.TypeString,
    28  				Required: true,
    29  				ForceNew: true,
    30  			},
    31  
    32  			"image": &schema.Schema{
    33  				Type:     schema.TypeString,
    34  				Optional: true,
    35  				ForceNew: true,
    36  			},
    37  
    38  			"size": &schema.Schema{
    39  				Type:     schema.TypeInt,
    40  				Optional: true,
    41  				ForceNew: true,
    42  			},
    43  
    44  			"type": &schema.Schema{
    45  				Type:     schema.TypeString,
    46  				Optional: true,
    47  				ForceNew: true,
    48  			},
    49  
    50  			"snapshot": &schema.Schema{
    51  				Type:     schema.TypeString,
    52  				Optional: true,
    53  				ForceNew: true,
    54  			},
    55  
    56  			"self_link": &schema.Schema{
    57  				Type:     schema.TypeString,
    58  				Computed: true,
    59  			},
    60  		},
    61  	}
    62  }
    63  
    64  func resourceComputeDiskCreate(d *schema.ResourceData, meta interface{}) error {
    65  	config := meta.(*Config)
    66  
    67  	// Get the zone
    68  	log.Printf("[DEBUG] Loading zone: %s", d.Get("zone").(string))
    69  	zone, err := config.clientCompute.Zones.Get(
    70  		config.Project, d.Get("zone").(string)).Do()
    71  	if err != nil {
    72  		return fmt.Errorf(
    73  			"Error loading zone '%s': %s", d.Get("zone").(string), err)
    74  	}
    75  
    76  	// Build the disk parameter
    77  	disk := &compute.Disk{
    78  		Name:   d.Get("name").(string),
    79  		SizeGb: int64(d.Get("size").(int)),
    80  	}
    81  
    82  	// If we were given a source image, load that.
    83  	if v, ok := d.GetOk("image"); ok {
    84  		log.Printf("[DEBUG] Resolving image name: %s", v.(string))
    85  		imageUrl, err := resolveImage(config, v.(string))
    86  		if err != nil {
    87  			return fmt.Errorf(
    88  				"Error resolving image name '%s': %s",
    89  				v.(string), err)
    90  		}
    91  
    92  		disk.SourceImage = imageUrl
    93  	}
    94  
    95  	if v, ok := d.GetOk("type"); ok {
    96  		log.Printf("[DEBUG] Loading disk type: %s", v.(string))
    97  		diskType, err := readDiskType(config, zone, v.(string))
    98  		if err != nil {
    99  			return fmt.Errorf(
   100  				"Error loading disk type '%s': %s",
   101  				v.(string), err)
   102  		}
   103  
   104  		disk.Type = diskType.SelfLink
   105  	}
   106  
   107  	if v, ok := d.GetOk("snapshot"); ok {
   108  		snapshotName := v.(string)
   109  		log.Printf("[DEBUG] Loading snapshot: %s", snapshotName)
   110  		snapshotData, err := config.clientCompute.Snapshots.Get(
   111  			config.Project, snapshotName).Do()
   112  
   113  		if err != nil {
   114  			return fmt.Errorf(
   115  				"Error loading snapshot '%s': %s",
   116  				snapshotName, err)
   117  		}
   118  
   119  		disk.SourceSnapshot = snapshotData.SelfLink
   120  	}
   121  
   122  	op, err := config.clientCompute.Disks.Insert(
   123  		config.Project, d.Get("zone").(string), disk).Do()
   124  	if err != nil {
   125  		return fmt.Errorf("Error creating disk: %s", err)
   126  	}
   127  
   128  	// It probably maybe worked, so store the ID now
   129  	d.SetId(disk.Name)
   130  
   131  	// Wait for the operation to complete
   132  	w := &OperationWaiter{
   133  		Service: config.clientCompute,
   134  		Op:      op,
   135  		Project: config.Project,
   136  		Zone:    d.Get("zone").(string),
   137  		Type:    OperationWaitZone,
   138  	}
   139  	state := w.Conf()
   140  
   141  	if disk.SourceSnapshot != "" {
   142  		//creating disk from snapshot takes some time
   143  		state.Timeout = 10 * time.Minute
   144  	} else {
   145  		state.Timeout = 2 * time.Minute
   146  	}
   147  
   148  	state.MinTimeout = 1 * time.Second
   149  	opRaw, err := state.WaitForState()
   150  	if err != nil {
   151  		return fmt.Errorf("Error waiting for disk to create: %s", err)
   152  	}
   153  	op = opRaw.(*compute.Operation)
   154  	if op.Error != nil {
   155  		// The resource didn't actually create
   156  		d.SetId("")
   157  
   158  		// Return the error
   159  		return OperationError(*op.Error)
   160  	}
   161  
   162  	return resourceComputeDiskRead(d, meta)
   163  }
   164  
   165  func resourceComputeDiskRead(d *schema.ResourceData, meta interface{}) error {
   166  	config := meta.(*Config)
   167  
   168  	disk, err := config.clientCompute.Disks.Get(
   169  		config.Project, d.Get("zone").(string), d.Id()).Do()
   170  	if err != nil {
   171  		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
   172  			// The resource doesn't exist anymore
   173  			d.SetId("")
   174  
   175  			return nil
   176  		}
   177  
   178  		return fmt.Errorf("Error reading disk: %s", err)
   179  	}
   180  
   181  	d.Set("self_link", disk.SelfLink)
   182  
   183  	return nil
   184  }
   185  
   186  func resourceComputeDiskDelete(d *schema.ResourceData, meta interface{}) error {
   187  	config := meta.(*Config)
   188  
   189  	// Delete the disk
   190  	op, err := config.clientCompute.Disks.Delete(
   191  		config.Project, d.Get("zone").(string), d.Id()).Do()
   192  	if err != nil {
   193  		return fmt.Errorf("Error deleting disk: %s", err)
   194  	}
   195  
   196  	// Wait for the operation to complete
   197  	w := &OperationWaiter{
   198  		Service: config.clientCompute,
   199  		Op:      op,
   200  		Project: config.Project,
   201  		Zone:    d.Get("zone").(string),
   202  		Type:    OperationWaitZone,
   203  	}
   204  	state := w.Conf()
   205  	state.Timeout = 2 * time.Minute
   206  	state.MinTimeout = 1 * time.Second
   207  	opRaw, err := state.WaitForState()
   208  	if err != nil {
   209  		return fmt.Errorf("Error waiting for disk to delete: %s", err)
   210  	}
   211  	op = opRaw.(*compute.Operation)
   212  	if op.Error != nil {
   213  		// Return the error
   214  		return OperationError(*op.Error)
   215  	}
   216  
   217  	d.SetId("")
   218  	return nil
   219  }