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 }