github.com/memsql/terraform@v0.7.0-rc2.0.20160706152241-21e2173e0a32/builtin/providers/vsphere/resource_vsphere_virtual_disk.go (about) 1 package vsphere 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/hashicorp/terraform/helper/schema" 8 "github.com/vmware/govmomi" 9 "github.com/vmware/govmomi/find" 10 "github.com/vmware/govmomi/object" 11 "github.com/vmware/govmomi/vim25/types" 12 "golang.org/x/net/context" 13 ) 14 15 type virtualDisk struct { 16 size int 17 vmdkPath string 18 initType string 19 adapterType string 20 datacenter string 21 datastore string 22 } 23 24 // Define VirtualDisk args 25 func resourceVSphereVirtualDisk() *schema.Resource { 26 return &schema.Resource{ 27 Create: resourceVSphereVirtualDiskCreate, 28 Read: resourceVSphereVirtualDiskRead, 29 Delete: resourceVSphereVirtualDiskDelete, 30 31 Schema: map[string]*schema.Schema{ 32 // Size in GB 33 "size": &schema.Schema{ 34 Type: schema.TypeInt, 35 Required: true, 36 ForceNew: true, //TODO Can this be optional (resize)? 37 }, 38 39 "vmdk_path": &schema.Schema{ 40 Type: schema.TypeString, 41 Required: true, 42 ForceNew: true, //TODO Can this be optional (move)? 43 }, 44 45 "type": &schema.Schema{ 46 Type: schema.TypeString, 47 Optional: true, 48 ForceNew: true, 49 Default: "eagerZeroedThick", 50 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 51 value := v.(string) 52 if value != "thin" && value != "eagerZeroedThick" { 53 errors = append(errors, fmt.Errorf( 54 "only 'thin' and 'eagerZeroedThick' are supported values for 'type'")) 55 } 56 return 57 }, 58 }, 59 60 "adapter_type": &schema.Schema{ 61 Type: schema.TypeString, 62 Optional: true, 63 ForceNew: true, 64 Default: "ide", 65 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 66 value := v.(string) 67 if value != "ide" && value != "busLogic" && value != "lsiLogic" { 68 errors = append(errors, fmt.Errorf( 69 "only 'ide', 'busLogic', and 'lsiLogic' are supported values for 'adapter_type'")) 70 } 71 return 72 }, 73 }, 74 75 "datacenter": &schema.Schema{ 76 Type: schema.TypeString, 77 Optional: true, 78 ForceNew: true, 79 }, 80 81 "datastore": &schema.Schema{ 82 Type: schema.TypeString, 83 Optional: true, 84 ForceNew: true, 85 }, 86 }, 87 } 88 } 89 90 func resourceVSphereVirtualDiskCreate(d *schema.ResourceData, meta interface{}) error { 91 log.Printf("[INFO] Creating Virtual Disk") 92 client := meta.(*govmomi.Client) 93 94 vDisk := virtualDisk{ 95 size: d.Get("size").(int), 96 } 97 98 if v, ok := d.GetOk("vmdk_path"); ok { 99 vDisk.vmdkPath = v.(string) 100 } 101 102 if v, ok := d.GetOk("type"); ok { 103 vDisk.initType = v.(string) 104 } 105 106 if v, ok := d.GetOk("adapter_type"); ok { 107 vDisk.adapterType = v.(string) 108 } 109 110 if v, ok := d.GetOk("datacenter"); ok { 111 vDisk.datacenter = v.(string) 112 } 113 114 if v, ok := d.GetOk("datastore"); ok { 115 vDisk.datastore = v.(string) 116 } 117 118 diskPath := fmt.Sprintf("[%v] %v", vDisk.datastore, vDisk.vmdkPath) 119 120 err := createHardDisk(client, vDisk.size, diskPath, vDisk.initType, vDisk.adapterType, vDisk.datacenter) 121 if err != nil { 122 return err 123 } 124 125 d.SetId(diskPath) 126 log.Printf("[DEBUG] Virtual Disk id: %v", diskPath) 127 128 return resourceVSphereVirtualDiskRead(d, meta) 129 } 130 131 func resourceVSphereVirtualDiskRead(d *schema.ResourceData, meta interface{}) error { 132 log.Printf("[DEBUG] Reading virtual disk.") 133 client := meta.(*govmomi.Client) 134 135 vDisk := virtualDisk{ 136 size: d.Get("size").(int), 137 } 138 139 if v, ok := d.GetOk("vmdk_path"); ok { 140 vDisk.vmdkPath = v.(string) 141 } 142 143 if v, ok := d.GetOk("type"); ok { 144 vDisk.initType = v.(string) 145 } 146 147 if v, ok := d.GetOk("adapter_type"); ok { 148 vDisk.adapterType = v.(string) 149 } 150 151 if v, ok := d.GetOk("datacenter"); ok { 152 vDisk.datacenter = v.(string) 153 } 154 155 if v, ok := d.GetOk("datastore"); ok { 156 vDisk.datastore = v.(string) 157 } 158 159 dc, err := getDatacenter(client, d.Get("datacenter").(string)) 160 if err != nil { 161 return err 162 } 163 164 finder := find.NewFinder(client.Client, true) 165 finder = finder.SetDatacenter(dc) 166 167 ds, err := finder.Datastore(context.TODO(), d.Get("datastore").(string)) 168 if err != nil { 169 return err 170 } 171 172 fileInfo, err := ds.Stat(context.TODO(), vDisk.vmdkPath) 173 if err != nil { 174 log.Printf("[DEBUG] resourceVSphereVirtualDiskRead - stat failed on: %v", vDisk.vmdkPath) 175 d.SetId("") 176 177 _, ok := err.(object.DatastoreNoSuchFileError) 178 if !ok { 179 return err 180 } 181 return nil 182 } 183 fileInfo = fileInfo.GetFileInfo() 184 log.Printf("[DEBUG] resourceVSphereVirtualDiskRead - fileinfo: %#v", fileInfo) 185 size := fileInfo.(*types.FileInfo).FileSize / 1024 / 1024 / 1024 186 187 d.SetId(vDisk.vmdkPath) 188 189 d.Set("size", size) 190 d.Set("vmdk_path", vDisk.vmdkPath) 191 d.Set("datacenter", d.Get("datacenter")) 192 d.Set("datastore", d.Get("datastore")) 193 // Todo collect and write type info 194 195 return nil 196 197 } 198 199 func resourceVSphereVirtualDiskDelete(d *schema.ResourceData, meta interface{}) error { 200 client := meta.(*govmomi.Client) 201 202 vDisk := virtualDisk{} 203 204 if v, ok := d.GetOk("vmdk_path"); ok { 205 vDisk.vmdkPath = v.(string) 206 } 207 if v, ok := d.GetOk("datastore"); ok { 208 vDisk.datastore = v.(string) 209 } 210 211 dc, err := getDatacenter(client, d.Get("datacenter").(string)) 212 if err != nil { 213 return err 214 } 215 diskPath := fmt.Sprintf("[%v] %v", vDisk.datastore, vDisk.vmdkPath) 216 217 virtualDiskManager := object.NewVirtualDiskManager(client.Client) 218 219 task, err := virtualDiskManager.DeleteVirtualDisk(context.TODO(), diskPath, dc) 220 if err != nil { 221 return err 222 } 223 224 _, err = task.WaitForResult(context.TODO(), nil) 225 if err != nil { 226 log.Printf("[INFO] Failed to delete disk: %v", err) 227 return err 228 } 229 230 log.Printf("[INFO] Deleted disk: %v", diskPath) 231 d.SetId("") 232 return nil 233 } 234 235 // createHardDisk creates a new Hard Disk. 236 func createHardDisk(client *govmomi.Client, size int, diskPath string, diskType string, adapterType string, dc string) error { 237 virtualDiskManager := object.NewVirtualDiskManager(client.Client) 238 spec := &types.FileBackedVirtualDiskSpec{ 239 VirtualDiskSpec: types.VirtualDiskSpec{ 240 AdapterType: adapterType, 241 DiskType: diskType, 242 }, 243 CapacityKb: int64(1024 * 1024 * size), 244 } 245 datacenter, err := getDatacenter(client, dc) 246 if err != nil { 247 return err 248 } 249 log.Printf("[DEBUG] Disk spec: %v", spec) 250 251 task, err := virtualDiskManager.CreateVirtualDisk(context.TODO(), diskPath, datacenter, spec) 252 if err != nil { 253 return err 254 } 255 256 _, err = task.WaitForResult(context.TODO(), nil) 257 if err != nil { 258 log.Printf("[INFO] Failed to create disk: %v", err) 259 return err 260 } 261 log.Printf("[INFO] Created disk.") 262 263 return nil 264 }