github.com/bendemaree/terraform@v0.5.4-0.20150613200311-f50d97d6eee6/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 }