github.com/ljosa/terraform@v0.7.0-rc2.0.20160617205345-fe540b408f59/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 return err 177 } 178 fileInfo = fileInfo.GetFileInfo() 179 log.Printf("[DEBUG] resourceVSphereVirtualDiskRead - fileinfo: %#v", fileInfo) 180 size := fileInfo.(*types.FileInfo).FileSize / 1024 / 1024 / 1024 181 182 d.SetId(vDisk.vmdkPath) 183 184 d.Set("size", size) 185 d.Set("vmdk_path", vDisk.vmdkPath) 186 d.Set("datacenter", d.Get("datacenter")) 187 d.Set("datastore", d.Get("datastore")) 188 // Todo collect and write type info 189 190 return nil 191 192 } 193 194 func resourceVSphereVirtualDiskDelete(d *schema.ResourceData, meta interface{}) error { 195 client := meta.(*govmomi.Client) 196 197 vDisk := virtualDisk{} 198 199 if v, ok := d.GetOk("vmdk_path"); ok { 200 vDisk.vmdkPath = v.(string) 201 } 202 if v, ok := d.GetOk("datastore"); ok { 203 vDisk.datastore = v.(string) 204 } 205 206 dc, err := getDatacenter(client, d.Get("datacenter").(string)) 207 if err != nil { 208 return err 209 } 210 diskPath := fmt.Sprintf("[%v] %v", vDisk.datastore, vDisk.vmdkPath) 211 212 virtualDiskManager := object.NewVirtualDiskManager(client.Client) 213 214 task, err := virtualDiskManager.DeleteVirtualDisk(context.TODO(), diskPath, dc) 215 if err != nil { 216 return err 217 } 218 219 _, err = task.WaitForResult(context.TODO(), nil) 220 if err != nil { 221 log.Printf("[INFO] Failed to delete disk: %v", err) 222 return err 223 } 224 225 log.Printf("[INFO] Deleted disk: %v", diskPath) 226 d.SetId("") 227 return nil 228 } 229 230 // createHardDisk creates a new Hard Disk. 231 func createHardDisk(client *govmomi.Client, size int, diskPath string, diskType string, adapterType string, dc string) error { 232 virtualDiskManager := object.NewVirtualDiskManager(client.Client) 233 spec := &types.FileBackedVirtualDiskSpec{ 234 VirtualDiskSpec: types.VirtualDiskSpec{ 235 AdapterType: adapterType, 236 DiskType: diskType, 237 }, 238 CapacityKb: int64(1024 * 1024 * size), 239 } 240 datacenter, err := getDatacenter(client, dc) 241 if err != nil { 242 return err 243 } 244 log.Printf("[DEBUG] Disk spec: %v", spec) 245 246 task, err := virtualDiskManager.CreateVirtualDisk(context.TODO(), diskPath, datacenter, spec) 247 if err != nil { 248 return err 249 } 250 251 _, err = task.WaitForResult(context.TODO(), nil) 252 if err != nil { 253 log.Printf("[INFO] Failed to create disk: %v", err) 254 return err 255 } 256 log.Printf("[INFO] Created disk.") 257 258 return nil 259 }