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