github.com/ricardclau/terraform@v0.6.17-0.20160519222547-283e3ae6b5a9/builtin/providers/vsphere/resource_vsphere_file.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/soap" 12 "golang.org/x/net/context" 13 ) 14 15 type file struct { 16 datacenter string 17 datastore string 18 sourceFile string 19 destinationFile string 20 } 21 22 func resourceVSphereFile() *schema.Resource { 23 return &schema.Resource{ 24 Create: resourceVSphereFileCreate, 25 Read: resourceVSphereFileRead, 26 Update: resourceVSphereFileUpdate, 27 Delete: resourceVSphereFileDelete, 28 29 Schema: map[string]*schema.Schema{ 30 "datacenter": { 31 Type: schema.TypeString, 32 Optional: true, 33 ForceNew: true, 34 }, 35 36 "datastore": { 37 Type: schema.TypeString, 38 Optional: true, 39 ForceNew: true, 40 }, 41 42 "source_file": { 43 Type: schema.TypeString, 44 Required: true, 45 ForceNew: true, 46 }, 47 48 "destination_file": { 49 Type: schema.TypeString, 50 Required: true, 51 }, 52 }, 53 } 54 } 55 56 func resourceVSphereFileCreate(d *schema.ResourceData, meta interface{}) error { 57 58 log.Printf("[DEBUG] creating file: %#v", d) 59 client := meta.(*govmomi.Client) 60 61 f := file{} 62 63 if v, ok := d.GetOk("datacenter"); ok { 64 f.datacenter = v.(string) 65 } 66 67 if v, ok := d.GetOk("datastore"); ok { 68 f.datastore = v.(string) 69 } else { 70 return fmt.Errorf("datastore argument is required") 71 } 72 73 if v, ok := d.GetOk("source_file"); ok { 74 f.sourceFile = v.(string) 75 } else { 76 return fmt.Errorf("source_file argument is required") 77 } 78 79 if v, ok := d.GetOk("destination_file"); ok { 80 f.destinationFile = v.(string) 81 } else { 82 return fmt.Errorf("destination_file argument is required") 83 } 84 85 err := createFile(client, &f) 86 if err != nil { 87 return err 88 } 89 90 d.SetId(fmt.Sprintf("[%v] %v/%v", f.datastore, f.datacenter, f.destinationFile)) 91 log.Printf("[INFO] Created file: %s", f.destinationFile) 92 93 return resourceVSphereFileRead(d, meta) 94 } 95 96 func createFile(client *govmomi.Client, f *file) error { 97 98 finder := find.NewFinder(client.Client, true) 99 100 dc, err := finder.Datacenter(context.TODO(), f.datacenter) 101 if err != nil { 102 return fmt.Errorf("error %s", err) 103 } 104 finder = finder.SetDatacenter(dc) 105 106 ds, err := getDatastore(finder, f.datastore) 107 if err != nil { 108 return fmt.Errorf("error %s", err) 109 } 110 111 dsurl, err := ds.URL(context.TODO(), dc, f.destinationFile) 112 if err != nil { 113 return err 114 } 115 116 p := soap.DefaultUpload 117 err = client.Client.UploadFile(f.sourceFile, dsurl, &p) 118 if err != nil { 119 return fmt.Errorf("error %s", err) 120 } 121 return nil 122 } 123 124 func resourceVSphereFileRead(d *schema.ResourceData, meta interface{}) error { 125 126 log.Printf("[DEBUG] reading file: %#v", d) 127 f := file{} 128 129 if v, ok := d.GetOk("datacenter"); ok { 130 f.datacenter = v.(string) 131 } 132 133 if v, ok := d.GetOk("datastore"); ok { 134 f.datastore = v.(string) 135 } else { 136 return fmt.Errorf("datastore argument is required") 137 } 138 139 if v, ok := d.GetOk("source_file"); ok { 140 f.sourceFile = v.(string) 141 } else { 142 return fmt.Errorf("source_file argument is required") 143 } 144 145 if v, ok := d.GetOk("destination_file"); ok { 146 f.destinationFile = v.(string) 147 } else { 148 return fmt.Errorf("destination_file argument is required") 149 } 150 151 client := meta.(*govmomi.Client) 152 finder := find.NewFinder(client.Client, true) 153 154 dc, err := finder.Datacenter(context.TODO(), f.datacenter) 155 if err != nil { 156 return fmt.Errorf("error %s", err) 157 } 158 finder = finder.SetDatacenter(dc) 159 160 ds, err := getDatastore(finder, f.datastore) 161 if err != nil { 162 return fmt.Errorf("error %s", err) 163 } 164 165 _, err = ds.Stat(context.TODO(), f.destinationFile) 166 if err != nil { 167 d.SetId("") 168 return err 169 } 170 171 return nil 172 } 173 174 func resourceVSphereFileUpdate(d *schema.ResourceData, meta interface{}) error { 175 176 log.Printf("[DEBUG] updating file: %#v", d) 177 if d.HasChange("destination_file") { 178 oldDestinationFile, newDestinationFile := d.GetChange("destination_file") 179 f := file{} 180 181 if v, ok := d.GetOk("datacenter"); ok { 182 f.datacenter = v.(string) 183 } 184 185 if v, ok := d.GetOk("datastore"); ok { 186 f.datastore = v.(string) 187 } else { 188 return fmt.Errorf("datastore argument is required") 189 } 190 191 if v, ok := d.GetOk("source_file"); ok { 192 f.sourceFile = v.(string) 193 } else { 194 return fmt.Errorf("source_file argument is required") 195 } 196 197 if v, ok := d.GetOk("destination_file"); ok { 198 f.destinationFile = v.(string) 199 } else { 200 return fmt.Errorf("destination_file argument is required") 201 } 202 203 client := meta.(*govmomi.Client) 204 dc, err := getDatacenter(client, f.datacenter) 205 if err != nil { 206 return err 207 } 208 209 finder := find.NewFinder(client.Client, true) 210 finder = finder.SetDatacenter(dc) 211 212 ds, err := getDatastore(finder, f.datastore) 213 if err != nil { 214 return fmt.Errorf("error %s", err) 215 } 216 217 fm := object.NewFileManager(client.Client) 218 task, err := fm.MoveDatastoreFile(context.TODO(), ds.Path(oldDestinationFile.(string)), dc, ds.Path(newDestinationFile.(string)), dc, true) 219 if err != nil { 220 return err 221 } 222 223 _, err = task.WaitForResult(context.TODO(), nil) 224 if err != nil { 225 return err 226 } 227 228 } 229 230 return nil 231 } 232 233 func resourceVSphereFileDelete(d *schema.ResourceData, meta interface{}) error { 234 235 log.Printf("[DEBUG] deleting file: %#v", d) 236 f := file{} 237 238 if v, ok := d.GetOk("datacenter"); ok { 239 f.datacenter = v.(string) 240 } 241 242 if v, ok := d.GetOk("datastore"); ok { 243 f.datastore = v.(string) 244 } else { 245 return fmt.Errorf("datastore argument is required") 246 } 247 248 if v, ok := d.GetOk("source_file"); ok { 249 f.sourceFile = v.(string) 250 } else { 251 return fmt.Errorf("source_file argument is required") 252 } 253 254 if v, ok := d.GetOk("destination_file"); ok { 255 f.destinationFile = v.(string) 256 } else { 257 return fmt.Errorf("destination_file argument is required") 258 } 259 260 client := meta.(*govmomi.Client) 261 262 err := deleteFile(client, &f) 263 if err != nil { 264 return err 265 } 266 267 d.SetId("") 268 return nil 269 } 270 271 func deleteFile(client *govmomi.Client, f *file) error { 272 273 dc, err := getDatacenter(client, f.datacenter) 274 if err != nil { 275 return err 276 } 277 278 finder := find.NewFinder(client.Client, true) 279 finder = finder.SetDatacenter(dc) 280 281 ds, err := getDatastore(finder, f.datastore) 282 if err != nil { 283 return fmt.Errorf("error %s", err) 284 } 285 286 fm := object.NewFileManager(client.Client) 287 task, err := fm.DeleteDatastoreFile(context.TODO(), ds.Path(f.destinationFile), dc) 288 if err != nil { 289 return err 290 } 291 292 _, err = task.WaitForResult(context.TODO(), nil) 293 if err != nil { 294 return err 295 } 296 return nil 297 } 298 299 // getDatastore gets datastore object 300 func getDatastore(f *find.Finder, ds string) (*object.Datastore, error) { 301 302 if ds != "" { 303 dso, err := f.Datastore(context.TODO(), ds) 304 return dso, err 305 } else { 306 dso, err := f.DefaultDatastore(context.TODO()) 307 return dso, err 308 } 309 }