github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/scaleway/resource_scaleway_server.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 resourceScalewayServer() *schema.Resource { 12 return &schema.Resource{ 13 Create: resourceScalewayServerCreate, 14 Read: resourceScalewayServerRead, 15 Update: resourceScalewayServerUpdate, 16 Delete: resourceScalewayServerDelete, 17 Importer: &schema.ResourceImporter{ 18 State: schema.ImportStatePassthrough, 19 }, 20 21 Schema: map[string]*schema.Schema{ 22 "name": { 23 Type: schema.TypeString, 24 Required: true, 25 }, 26 "image": { 27 Type: schema.TypeString, 28 Required: true, 29 ForceNew: true, 30 }, 31 "type": { 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 }, 36 "bootscript": { 37 Type: schema.TypeString, 38 Optional: true, 39 }, 40 "tags": { 41 Type: schema.TypeList, 42 Elem: &schema.Schema{ 43 Type: schema.TypeString, 44 }, 45 Optional: true, 46 }, 47 "enable_ipv6": { 48 Type: schema.TypeBool, 49 Optional: true, 50 Default: false, 51 }, 52 "dynamic_ip_required": { 53 Type: schema.TypeBool, 54 Optional: true, 55 }, 56 "security_group": { 57 Type: schema.TypeString, 58 Optional: true, 59 }, 60 "volume": { 61 Type: schema.TypeList, 62 Optional: true, 63 ForceNew: true, 64 Elem: &schema.Resource{ 65 Schema: map[string]*schema.Schema{ 66 "size_in_gb": { 67 Type: schema.TypeInt, 68 Required: true, 69 ValidateFunc: validateVolumeSize, 70 }, 71 "type": { 72 Type: schema.TypeString, 73 Required: true, 74 ValidateFunc: validateVolumeType, 75 }, 76 "volume_id": { 77 Type: schema.TypeString, 78 Computed: true, 79 }, 80 }, 81 }, 82 }, 83 "private_ip": { 84 Type: schema.TypeString, 85 Computed: true, 86 }, 87 "public_ip": { 88 Type: schema.TypeString, 89 Computed: true, 90 }, 91 "public_ipv6": { 92 Type: schema.TypeString, 93 Computed: true, 94 }, 95 "state": { 96 Type: schema.TypeString, 97 Optional: true, 98 Computed: true, 99 }, 100 "state_detail": { 101 Type: schema.TypeString, 102 Computed: true, 103 }, 104 }, 105 } 106 } 107 108 func resourceScalewayServerCreate(d *schema.ResourceData, m interface{}) error { 109 scaleway := m.(*Client).scaleway 110 111 mu.Lock() 112 defer mu.Unlock() 113 114 image := d.Get("image").(string) 115 var server = api.ScalewayServerDefinition{ 116 Name: d.Get("name").(string), 117 Image: String(image), 118 Organization: scaleway.Organization, 119 EnableIPV6: d.Get("enable_ipv6").(bool), 120 SecurityGroup: d.Get("security_group").(string), 121 } 122 123 server.DynamicIPRequired = Bool(d.Get("dynamic_ip_required").(bool)) 124 server.CommercialType = d.Get("type").(string) 125 126 if bootscript, ok := d.GetOk("bootscript"); ok { 127 server.Bootscript = String(bootscript.(string)) 128 } 129 130 if vs, ok := d.GetOk("volume"); ok { 131 server.Volumes = make(map[string]string) 132 133 volumes := vs.([]interface{}) 134 for i, v := range volumes { 135 volume := v.(map[string]interface{}) 136 137 volumeID, err := scaleway.PostVolume(api.ScalewayVolumeDefinition{ 138 Size: uint64(volume["size_in_gb"].(int)) * gb, 139 Type: volume["type"].(string), 140 Name: fmt.Sprintf("%s-%d", server.Name, volume["size_in_gb"].(int)), 141 }) 142 if err != nil { 143 return err 144 } 145 volume["volume_id"] = volumeID 146 volumes[i] = volume 147 server.Volumes[fmt.Sprintf("%d", i+1)] = volumeID 148 } 149 d.Set("volume", volumes) 150 } 151 152 if raw, ok := d.GetOk("tags"); ok { 153 for _, tag := range raw.([]interface{}) { 154 server.Tags = append(server.Tags, tag.(string)) 155 } 156 } 157 158 id, err := scaleway.PostServer(server) 159 if err != nil { 160 return err 161 } 162 163 d.SetId(id) 164 if d.Get("state").(string) != "stopped" { 165 err = scaleway.PostServerAction(id, "poweron") 166 if err != nil { 167 return err 168 } 169 170 err = waitForServerState(scaleway, id, "running") 171 } 172 173 if err != nil { 174 return err 175 } 176 177 return resourceScalewayServerRead(d, m) 178 } 179 180 func resourceScalewayServerRead(d *schema.ResourceData, m interface{}) error { 181 scaleway := m.(*Client).scaleway 182 server, err := scaleway.GetServer(d.Id()) 183 184 if err != nil { 185 if serr, ok := err.(api.ScalewayAPIError); ok { 186 log.Printf("[DEBUG] Error reading server: %q\n", serr.APIMessage) 187 188 if serr.StatusCode == 404 { 189 d.SetId("") 190 return nil 191 } 192 } 193 194 return err 195 } 196 197 d.Set("name", server.Name) 198 d.Set("image", server.Image.Identifier) 199 d.Set("type", server.CommercialType) 200 d.Set("enable_ipv6", server.EnableIPV6) 201 d.Set("private_ip", server.PrivateIP) 202 d.Set("public_ip", server.PublicAddress.IP) 203 204 if server.EnableIPV6 { 205 d.Set("public_ipv6", server.IPV6.Address) 206 } 207 208 d.Set("state", server.State) 209 d.Set("state_detail", server.StateDetail) 210 d.Set("tags", server.Tags) 211 212 d.SetConnInfo(map[string]string{ 213 "type": "ssh", 214 "host": server.PublicAddress.IP, 215 }) 216 217 return nil 218 } 219 220 func resourceScalewayServerUpdate(d *schema.ResourceData, m interface{}) error { 221 scaleway := m.(*Client).scaleway 222 223 mu.Lock() 224 defer mu.Unlock() 225 226 var req api.ScalewayServerPatchDefinition 227 if d.HasChange("name") { 228 name := d.Get("name").(string) 229 req.Name = &name 230 } 231 232 if d.HasChange("tags") { 233 if raw, ok := d.GetOk("tags"); ok { 234 var tags []string 235 for _, tag := range raw.([]interface{}) { 236 tags = append(tags, tag.(string)) 237 } 238 req.Tags = &tags 239 } 240 } 241 242 if d.HasChange("enable_ipv6") { 243 req.EnableIPV6 = Bool(d.Get("enable_ipv6").(bool)) 244 } 245 246 if d.HasChange("dynamic_ip_required") { 247 req.DynamicIPRequired = Bool(d.Get("dynamic_ip_required").(bool)) 248 } 249 250 if d.HasChange("security_group") { 251 req.SecurityGroup = &api.ScalewaySecurityGroup{ 252 Identifier: d.Get("security_group").(string), 253 } 254 } 255 256 if err := scaleway.PatchServer(d.Id(), req); err != nil { 257 return fmt.Errorf("Failed patching scaleway server: %q", err) 258 } 259 260 return resourceScalewayServerRead(d, m) 261 } 262 263 func resourceScalewayServerDelete(d *schema.ResourceData, m interface{}) error { 264 scaleway := m.(*Client).scaleway 265 266 mu.Lock() 267 defer mu.Unlock() 268 269 s, err := scaleway.GetServer(d.Id()) 270 if err != nil { 271 return err 272 } 273 274 if s.State == "stopped" { 275 return deleteStoppedServer(scaleway, s) 276 } 277 278 err = deleteRunningServer(scaleway, s) 279 280 if err == nil { 281 d.SetId("") 282 } 283 284 return err 285 }