github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/profitbricks/resource_profitbricks_volume.go (about)

     1  package profitbricks
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/hashicorp/terraform/helper/schema"
     6  	"github.com/profitbricks/profitbricks-sdk-go"
     7  	"log"
     8  )
     9  
    10  func resourceProfitBricksVolume() *schema.Resource {
    11  	return &schema.Resource{
    12  		Create: resourceProfitBricksVolumeCreate,
    13  		Read:   resourceProfitBricksVolumeRead,
    14  		Update: resourceProfitBricksVolumeUpdate,
    15  		Delete: resourceProfitBricksVolumeDelete,
    16  		Schema: map[string]*schema.Schema{
    17  			"image_name": {
    18  				Type:     schema.TypeString,
    19  				Optional: true,
    20  			},
    21  			"size": {
    22  				Type:     schema.TypeInt,
    23  				Required: true,
    24  			},
    25  
    26  			"disk_type": {
    27  				Type:     schema.TypeString,
    28  				Required: true,
    29  			},
    30  			"image_password": {
    31  				Type:     schema.TypeString,
    32  				Optional: true,
    33  			},
    34  			"licence_type": {
    35  				Type:     schema.TypeString,
    36  				Optional: true,
    37  			},
    38  			"ssh_key_path": {
    39  				Type:     schema.TypeList,
    40  				Elem:     &schema.Schema{Type: schema.TypeString},
    41  				Optional: true,
    42  			},
    43  			"sshkey": {
    44  				Type:     schema.TypeString,
    45  				Computed: true,
    46  			},
    47  			"bus": {
    48  				Type:     schema.TypeString,
    49  				Optional: true,
    50  			},
    51  			"name": {
    52  				Type:     schema.TypeString,
    53  				Optional: true,
    54  			},
    55  			"availability_zone": {
    56  				Type:     schema.TypeString,
    57  				Optional: true,
    58  			},
    59  			"server_id": {
    60  				Type:     schema.TypeString,
    61  				Required: true,
    62  			},
    63  			"datacenter_id": {
    64  				Type:     schema.TypeString,
    65  				Required: true,
    66  			},
    67  		},
    68  	}
    69  }
    70  
    71  func resourceProfitBricksVolumeCreate(d *schema.ResourceData, meta interface{}) error {
    72  	var err error
    73  	var ssh_keypath []interface{}
    74  	dcId := d.Get("datacenter_id").(string)
    75  	serverId := d.Get("server_id").(string)
    76  	imagePassword := d.Get("image_password").(string)
    77  	ssh_keypath = d.Get("ssh_key_path").([]interface{})
    78  	image_name := d.Get("image_name").(string)
    79  
    80  	licenceType := d.Get("licence_type").(string)
    81  
    82  	if image_name == "" && licenceType == "" {
    83  		return fmt.Errorf("Either 'image_name', or 'licenceType' must be set.")
    84  	}
    85  
    86  	var publicKeys []string
    87  	if len(ssh_keypath) != 0 {
    88  		for _, path := range ssh_keypath {
    89  			log.Printf("[DEBUG] Reading file %s", path)
    90  			publicKey, err := readPublicKey(path.(string))
    91  			if err != nil {
    92  				return fmt.Errorf("Error fetching sshkey from file (%s) (%s)", path, err.Error())
    93  			}
    94  			publicKeys = append(publicKeys, publicKey)
    95  		}
    96  	}
    97  
    98  	var image string
    99  	if image_name != "" {
   100  		if !IsValidUUID(image_name) {
   101  			if imagePassword == "" && len(ssh_keypath) == 0 {
   102  				return fmt.Errorf("Either 'image_password' or 'sshkey' must be provided.")
   103  			}
   104  			image = getImageId(d.Get("datacenter_id").(string), image_name, d.Get("disk_type").(string))
   105  		} else {
   106  			img := profitbricks.GetImage(image_name)
   107  			if img.StatusCode > 299 {
   108  				return fmt.Errorf("Error fetching image: %s", img.Response)
   109  			}
   110  			if img.Properties.Public == true {
   111  				if imagePassword == "" && len(ssh_keypath) == 0 {
   112  					return fmt.Errorf("Either 'image_password' or 'sshkey' must be provided.")
   113  				}
   114  				image = image_name
   115  			} else {
   116  				image = image_name
   117  			}
   118  		}
   119  	}
   120  
   121  	volume := profitbricks.Volume{
   122  		Properties: profitbricks.VolumeProperties{
   123  			Name:          d.Get("name").(string),
   124  			Size:          d.Get("size").(int),
   125  			Type:          d.Get("disk_type").(string),
   126  			ImagePassword: imagePassword,
   127  			Image:         image,
   128  			Bus:           d.Get("bus").(string),
   129  			LicenceType:   licenceType,
   130  		},
   131  	}
   132  
   133  	if len(publicKeys) != 0 {
   134  		volume.Properties.SshKeys = publicKeys
   135  
   136  	} else {
   137  		volume.Properties.SshKeys = nil
   138  	}
   139  
   140  	if _, ok := d.GetOk("availability_zone"); ok {
   141  		raw := d.Get("availability_zone").(string)
   142  		volume.Properties.AvailabilityZone = raw
   143  	}
   144  
   145  	volume = profitbricks.CreateVolume(dcId, volume)
   146  
   147  	if volume.StatusCode > 299 {
   148  		return fmt.Errorf("An error occured while creating a volume: %s", volume.Response)
   149  	}
   150  
   151  	err = waitTillProvisioned(meta, volume.Headers.Get("Location"))
   152  	if err != nil {
   153  		return err
   154  	}
   155  	volume = profitbricks.AttachVolume(dcId, serverId, volume.Id)
   156  	if volume.StatusCode > 299 {
   157  		return fmt.Errorf("An error occured while attaching a volume dcId: %s server_id: %s ID: %s Response: %s", dcId, serverId, volume.Id, volume.Response)
   158  	}
   159  
   160  	err = waitTillProvisioned(meta, volume.Headers.Get("Location"))
   161  	if err != nil {
   162  		return err
   163  	}
   164  	d.SetId(volume.Id)
   165  
   166  	return resourceProfitBricksVolumeRead(d, meta)
   167  }
   168  
   169  func resourceProfitBricksVolumeRead(d *schema.ResourceData, meta interface{}) error {
   170  	config := meta.(*Config)
   171  	profitbricks.SetAuth(config.Username, config.Password)
   172  
   173  	dcId := d.Get("datacenter_id").(string)
   174  
   175  	volume := profitbricks.GetVolume(dcId, d.Id())
   176  
   177  	if volume.StatusCode > 299 {
   178  		if volume.StatusCode == 404 {
   179  			d.SetId("")
   180  			return nil
   181  		}
   182  		return fmt.Errorf("Error occured while fetching a volume ID %s %s", d.Id(), volume.Response)
   183  	}
   184  
   185  	if volume.StatusCode > 299 {
   186  		return fmt.Errorf("An error occured while fetching a volume ID %s %s", d.Id(), volume.Response)
   187  
   188  	}
   189  
   190  	d.Set("name", volume.Properties.Name)
   191  	d.Set("disk_type", volume.Properties.Type)
   192  	d.Set("size", volume.Properties.Size)
   193  	d.Set("bus", volume.Properties.Bus)
   194  	d.Set("image_name", volume.Properties.Image)
   195  
   196  	return nil
   197  }
   198  
   199  func resourceProfitBricksVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
   200  	properties := profitbricks.VolumeProperties{}
   201  	dcId := d.Get("datacenter_id").(string)
   202  
   203  	if d.HasChange("name") {
   204  		_, newValue := d.GetChange("name")
   205  		properties.Name = newValue.(string)
   206  	}
   207  	if d.HasChange("disk_type") {
   208  		_, newValue := d.GetChange("disk_type")
   209  		properties.Type = newValue.(string)
   210  	}
   211  	if d.HasChange("size") {
   212  		_, newValue := d.GetChange("size")
   213  		properties.Size = newValue.(int)
   214  	}
   215  	if d.HasChange("bus") {
   216  		_, newValue := d.GetChange("bus")
   217  		properties.Bus = newValue.(string)
   218  	}
   219  	if d.HasChange("availability_zone") {
   220  		_, newValue := d.GetChange("availability_zone")
   221  		properties.AvailabilityZone = newValue.(string)
   222  	}
   223  
   224  	volume := profitbricks.PatchVolume(dcId, d.Id(), properties)
   225  	err := waitTillProvisioned(meta, volume.Headers.Get("Location"))
   226  	if err != nil {
   227  		return err
   228  	}
   229  	if volume.StatusCode > 299 {
   230  		return fmt.Errorf("An error occured while updating a volume ID %s %s", d.Id(), volume.Response)
   231  
   232  	}
   233  	err = resourceProfitBricksVolumeRead(d, meta)
   234  	if err != nil {
   235  		return err
   236  	}
   237  	d.SetId(d.Get("server_id").(string))
   238  	err = resourceProfitBricksServerRead(d, meta)
   239  	if err != nil {
   240  		return err
   241  	}
   242  
   243  	d.SetId(volume.Id)
   244  	return nil
   245  }
   246  
   247  func resourceProfitBricksVolumeDelete(d *schema.ResourceData, meta interface{}) error {
   248  	dcId := d.Get("datacenter_id").(string)
   249  
   250  	resp := profitbricks.DeleteVolume(dcId, d.Id())
   251  	if resp.StatusCode > 299 {
   252  		return fmt.Errorf("An error occured while deleting a volume ID %s %s", d.Id(), string(resp.Body))
   253  
   254  	}
   255  	err := waitTillProvisioned(meta, resp.Headers.Get("Location"))
   256  	if err != nil {
   257  		return err
   258  	}
   259  	d.SetId("")
   260  	return nil
   261  }