terraform/builtin/providers/profitbricks/resource_profitbricks_volum...

243 lines
6.1 KiB
Go

package profitbricks
import (
"fmt"
"github.com/hashicorp/terraform/helper/schema"
"github.com/profitbricks/profitbricks-sdk-go"
"log"
)
func resourceProfitBricksVolume() *schema.Resource {
return &schema.Resource{
Create: resourceProfitBricksVolumeCreate,
Read: resourceProfitBricksVolumeRead,
Update: resourceProfitBricksVolumeUpdate,
Delete: resourceProfitBricksVolumeDelete,
Schema: map[string]*schema.Schema{
"image_name": {
Type: schema.TypeString,
Optional: true,
},
"size": {
Type: schema.TypeInt,
Required: true,
},
"disk_type": {
Type: schema.TypeString,
Required: true,
},
"image_password": {
Type: schema.TypeString,
Optional: true,
},
"licence_type": {
Type: schema.TypeString,
Optional: true,
},
"ssh_key_path": {
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"sshkey": {
Type: schema.TypeString,
Computed: true,
},
"bus": {
Type: schema.TypeString,
Optional: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
},
"availability_zone": {
Type: schema.TypeString,
Optional: true,
},
"server_id": {
Type: schema.TypeString,
Required: true,
},
"datacenter_id": {
Type: schema.TypeString,
Required: true,
},
},
}
}
func resourceProfitBricksVolumeCreate(d *schema.ResourceData, meta interface{}) error {
var err error
var ssh_keypath []interface{}
dcId := d.Get("datacenter_id").(string)
serverId := d.Get("server_id").(string)
imagePassword := d.Get("image_password").(string)
ssh_keypath = d.Get("ssh_key_path").([]interface{})
image_name := d.Get("image_name").(string)
if image_name != "" {
if imagePassword == "" && len(ssh_keypath) == 0 {
return fmt.Errorf("Either 'image_password' or 'sshkey' must be provided.")
}
}
licenceType := d.Get("licence_type").(string)
if image_name == "" && licenceType == "" {
return fmt.Errorf("Either 'image_name', or 'licenceType' must be set.")
}
var publicKeys []string
if len(ssh_keypath) != 0 {
for _, path := range ssh_keypath {
log.Printf("[DEBUG] Reading file %s", path)
publicKey, err := readPublicKey(path.(string))
if err != nil {
return fmt.Errorf("Error fetching sshkey from file (%s) (%s)", path, err.Error())
}
publicKeys = append(publicKeys, publicKey)
}
}
var image string
if !IsValidUUID(image_name) {
image = getImageId(d.Get("datacenter_id").(string), image_name, d.Get("disk_type").(string))
} else {
image = image_name
}
volume := profitbricks.Volume{
Properties: profitbricks.VolumeProperties{
Name: d.Get("name").(string),
Size: d.Get("size").(int),
Type: d.Get("disk_type").(string),
ImagePassword: imagePassword,
Image: image,
Bus: d.Get("bus").(string),
LicenceType: licenceType,
},
}
if len(publicKeys) != 0 {
volume.Properties.SshKeys = publicKeys
} else {
volume.Properties.SshKeys = nil
}
if _, ok := d.GetOk("availability_zone"); ok {
raw := d.Get("availability_zone").(string)
volume.Properties.AvailabilityZone = raw
}
volume = profitbricks.CreateVolume(dcId, volume)
if volume.StatusCode > 299 {
return fmt.Errorf("An error occured while creating a volume: %s", volume.Response)
}
err = waitTillProvisioned(meta, volume.Headers.Get("Location"))
if err != nil {
return err
}
volume = profitbricks.AttachVolume(dcId, serverId, volume.Id)
if volume.StatusCode > 299 {
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)
}
err = waitTillProvisioned(meta, volume.Headers.Get("Location"))
if err != nil {
return err
}
d.SetId(volume.Id)
return resourceProfitBricksVolumeRead(d, meta)
}
func resourceProfitBricksVolumeRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
profitbricks.SetAuth(config.Username, config.Password)
dcId := d.Get("datacenter_id").(string)
volume := profitbricks.GetVolume(dcId, d.Id())
if volume.StatusCode > 299 {
return fmt.Errorf("An error occured while fetching a volume ID %s %s", d.Id(), volume.Response)
}
d.Set("name", volume.Properties.Name)
d.Set("disk_type", volume.Properties.Type)
d.Set("size", volume.Properties.Size)
d.Set("bus", volume.Properties.Bus)
d.Set("image_name", volume.Properties.Image)
return nil
}
func resourceProfitBricksVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
properties := profitbricks.VolumeProperties{}
dcId := d.Get("datacenter_id").(string)
if d.HasChange("name") {
_, newValue := d.GetChange("name")
properties.Name = newValue.(string)
}
if d.HasChange("disk_type") {
_, newValue := d.GetChange("disk_type")
properties.Type = newValue.(string)
}
if d.HasChange("size") {
_, newValue := d.GetChange("size")
properties.Size = newValue.(int)
}
if d.HasChange("bus") {
_, newValue := d.GetChange("bus")
properties.Bus = newValue.(string)
}
if d.HasChange("availability_zone") {
_, newValue := d.GetChange("availability_zone")
properties.AvailabilityZone = newValue.(string)
}
volume := profitbricks.PatchVolume(dcId, d.Id(), properties)
err := waitTillProvisioned(meta, volume.Headers.Get("Location"))
if err != nil {
return err
}
if volume.StatusCode > 299 {
return fmt.Errorf("An error occured while updating a volume ID %s %s", d.Id(), volume.Response)
}
err = resourceProfitBricksVolumeRead(d, meta)
if err != nil {
return err
}
d.SetId(d.Get("server_id").(string))
err = resourceProfitBricksServerRead(d, meta)
if err != nil {
return err
}
d.SetId(volume.Id)
return nil
}
func resourceProfitBricksVolumeDelete(d *schema.ResourceData, meta interface{}) error {
dcId := d.Get("datacenter_id").(string)
resp := profitbricks.DeleteVolume(dcId, d.Id())
if resp.StatusCode > 299 {
return fmt.Errorf("An error occured while deleting a volume ID %s %s", d.Id(), string(resp.Body))
}
err := waitTillProvisioned(meta, resp.Headers.Get("Location"))
if err != nil {
return err
}
d.SetId("")
return nil
}