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  }