github.com/richardbowden/terraform@v0.6.12-0.20160901200758-30ea22c25211/builtin/providers/scaleway/resource_scaleway_volume_attachment.go (about) 1 package scaleway 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/hashicorp/terraform/helper/schema" 8 "github.com/scaleway/scaleway-cli/pkg/api" 9 ) 10 11 func resourceScalewayVolumeAttachment() *schema.Resource { 12 return &schema.Resource{ 13 Create: resourceScalewayVolumeAttachmentCreate, 14 Read: resourceScalewayVolumeAttachmentRead, 15 Delete: resourceScalewayVolumeAttachmentDelete, 16 Schema: map[string]*schema.Schema{ 17 "server": &schema.Schema{ 18 Type: schema.TypeString, 19 Required: true, 20 ForceNew: true, 21 }, 22 "volume": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 }, 27 }, 28 } 29 } 30 31 func resourceScalewayVolumeAttachmentCreate(d *schema.ResourceData, m interface{}) error { 32 scaleway := m.(*Client).scaleway 33 34 var startServerAgain = false 35 server, err := scaleway.GetServer(d.Get("server").(string)) 36 if err != nil { 37 fmt.Printf("Failed getting server: %q", err) 38 return err 39 } 40 41 // volumes can only be modified when the server is powered off 42 if server.State != "stopped" { 43 startServerAgain = true 44 45 if err := scaleway.PostServerAction(server.Identifier, "poweroff"); err != nil { 46 return err 47 } 48 49 if err := waitForServerState(scaleway, server.Identifier, "stopped"); err != nil { 50 return err 51 } 52 } 53 54 volumes := make(map[string]api.ScalewayVolume) 55 for i, volume := range server.Volumes { 56 volumes[i] = volume 57 } 58 59 vol, err := scaleway.GetVolume(d.Get("volume").(string)) 60 if err != nil { 61 return err 62 } 63 volumes[fmt.Sprintf("%d", len(volumes)+1)] = *vol 64 65 // the API request requires most volume attributes to be unset to succeed 66 for k, v := range volumes { 67 v.Size = 0 68 v.CreationDate = "" 69 v.Organization = "" 70 v.ModificationDate = "" 71 v.VolumeType = "" 72 v.Server = nil 73 v.ExportURI = "" 74 75 volumes[k] = v 76 } 77 78 var req = api.ScalewayServerPatchDefinition{ 79 Volumes: &volumes, 80 } 81 if err := scaleway.PatchServer(d.Get("server").(string), req); err != nil { 82 return fmt.Errorf("Failed attaching volume to server: %q", err) 83 } 84 85 if startServerAgain { 86 if err := scaleway.PostServerAction(d.Get("server").(string), "poweron"); err != nil { 87 return err 88 } 89 90 if err := waitForServerState(scaleway, d.Get("server").(string), "running"); err != nil { 91 return err 92 } 93 } 94 95 d.SetId(fmt.Sprintf("scaleway-server:%s/volume/%s", d.Get("server").(string), d.Get("volume").(string))) 96 97 return resourceScalewayVolumeAttachmentRead(d, m) 98 } 99 100 func resourceScalewayVolumeAttachmentRead(d *schema.ResourceData, m interface{}) error { 101 scaleway := m.(*Client).scaleway 102 103 server, err := scaleway.GetServer(d.Get("server").(string)) 104 if err != nil { 105 if serr, ok := err.(api.ScalewayAPIError); ok { 106 log.Printf("[DEBUG] Error reading server: %q\n", serr.APIMessage) 107 108 if serr.StatusCode == 404 { 109 d.SetId("") 110 return nil 111 } 112 } 113 return err 114 } 115 116 if _, err := scaleway.GetVolume(d.Get("volume").(string)); err != nil { 117 if serr, ok := err.(api.ScalewayAPIError); ok { 118 log.Printf("[DEBUG] Error reading volume: %q\n", serr.APIMessage) 119 120 if serr.StatusCode == 404 { 121 d.SetId("") 122 return nil 123 } 124 } 125 return err 126 } 127 128 for _, volume := range server.Volumes { 129 if volume.Identifier == d.Get("volume").(string) { 130 return nil 131 } 132 } 133 134 log.Printf("[DEBUG] Volume %q not attached to server %q\n", d.Get("volume").(string), d.Get("server").(string)) 135 d.SetId("") 136 return nil 137 } 138 139 func resourceScalewayVolumeAttachmentDelete(d *schema.ResourceData, m interface{}) error { 140 scaleway := m.(*Client).scaleway 141 var startServerAgain = false 142 143 server, err := scaleway.GetServer(d.Get("server").(string)) 144 if err != nil { 145 return err 146 } 147 148 // volumes can only be modified when the server is powered off 149 if server.State != "stopped" { 150 startServerAgain = true 151 152 if err := scaleway.PostServerAction(server.Identifier, "poweroff"); err != nil { 153 return err 154 } 155 156 if err := waitForServerState(scaleway, server.Identifier, "stopped"); err != nil { 157 return err 158 } 159 } 160 161 volumes := make(map[string]api.ScalewayVolume) 162 for _, volume := range server.Volumes { 163 if volume.Identifier != d.Get("volume").(string) { 164 volumes[fmt.Sprintf("%d", len(volumes))] = volume 165 } 166 } 167 168 // the API request requires most volume attributes to be unset to succeed 169 for k, v := range volumes { 170 v.Size = 0 171 v.CreationDate = "" 172 v.Organization = "" 173 v.ModificationDate = "" 174 v.VolumeType = "" 175 v.Server = nil 176 v.ExportURI = "" 177 178 volumes[k] = v 179 } 180 181 var req = api.ScalewayServerPatchDefinition{ 182 Volumes: &volumes, 183 } 184 if err := scaleway.PatchServer(d.Get("server").(string), req); err != nil { 185 return err 186 } 187 188 if startServerAgain { 189 if err := scaleway.PostServerAction(d.Get("server").(string), "poweron"); err != nil { 190 return err 191 } 192 193 if err := waitForServerState(scaleway, d.Get("server").(string), "running"); err != nil { 194 return err 195 } 196 } 197 198 d.SetId("") 199 200 return nil 201 }