github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/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 "state": &schema.Schema{ 92 Type: schema.TypeString, 93 Optional: true, 94 Computed: true, 95 }, 96 "state_detail": &schema.Schema{ 97 Type: schema.TypeString, 98 Computed: true, 99 }, 100 }, 101 } 102 } 103 104 func resourceScalewayServerCreate(d *schema.ResourceData, m interface{}) error { 105 scaleway := m.(*Client).scaleway 106 107 image := d.Get("image").(string) 108 var server = api.ScalewayServerDefinition{ 109 Name: d.Get("name").(string), 110 Image: String(image), 111 Organization: scaleway.Organization, 112 EnableIPV6: d.Get("enable_ipv6").(bool), 113 SecurityGroup: d.Get("security_group").(string), 114 } 115 116 server.DynamicIPRequired = Bool(d.Get("dynamic_ip_required").(bool)) 117 server.CommercialType = d.Get("type").(string) 118 119 if bootscript, ok := d.GetOk("bootscript"); ok { 120 server.Bootscript = String(bootscript.(string)) 121 } 122 123 if vs, ok := d.GetOk("volume"); ok { 124 server.Volumes = make(map[string]string) 125 126 volumes := vs.([]interface{}) 127 for i, v := range volumes { 128 volume := v.(map[string]interface{}) 129 130 volumeID, err := scaleway.PostVolume(api.ScalewayVolumeDefinition{ 131 Size: uint64(volume["size_in_gb"].(int)) * gb, 132 Type: volume["type"].(string), 133 Name: fmt.Sprintf("%s-%d", server.Name, volume["size_in_gb"].(int)), 134 }) 135 if err != nil { 136 return err 137 } 138 volume["volume_id"] = volumeID 139 volumes[i] = volume 140 server.Volumes[fmt.Sprintf("%d", i+1)] = volumeID 141 } 142 d.Set("volume", volumes) 143 } 144 145 if raw, ok := d.GetOk("tags"); ok { 146 for _, tag := range raw.([]interface{}) { 147 server.Tags = append(server.Tags, tag.(string)) 148 } 149 } 150 151 id, err := scaleway.PostServer(server) 152 if err != nil { 153 return err 154 } 155 156 d.SetId(id) 157 if d.Get("state").(string) != "stopped" { 158 err = scaleway.PostServerAction(id, "poweron") 159 if err != nil { 160 return err 161 } 162 163 err = waitForServerState(scaleway, id, "running") 164 } 165 166 if err != nil { 167 return err 168 } 169 170 return resourceScalewayServerRead(d, m) 171 } 172 173 func resourceScalewayServerRead(d *schema.ResourceData, m interface{}) error { 174 scaleway := m.(*Client).scaleway 175 server, err := scaleway.GetServer(d.Id()) 176 177 if err != nil { 178 if serr, ok := err.(api.ScalewayAPIError); ok { 179 log.Printf("[DEBUG] Error reading server: %q\n", serr.APIMessage) 180 181 if serr.StatusCode == 404 { 182 d.SetId("") 183 return nil 184 } 185 } 186 187 return err 188 } 189 190 d.Set("name", server.Name) 191 d.Set("image", server.Image.Identifier) 192 d.Set("type", server.CommercialType) 193 d.Set("enable_ipv6", server.EnableIPV6) 194 d.Set("private_ip", server.PrivateIP) 195 d.Set("public_ip", server.PublicAddress.IP) 196 197 d.Set("state", server.State) 198 d.Set("state_detail", server.StateDetail) 199 d.Set("tags", server.Tags) 200 201 d.SetConnInfo(map[string]string{ 202 "type": "ssh", 203 "host": server.PublicAddress.IP, 204 }) 205 206 return nil 207 } 208 209 func resourceScalewayServerUpdate(d *schema.ResourceData, m interface{}) error { 210 scaleway := m.(*Client).scaleway 211 212 var req api.ScalewayServerPatchDefinition 213 214 if d.HasChange("name") { 215 name := d.Get("name").(string) 216 req.Name = &name 217 } 218 219 if d.HasChange("tags") { 220 if raw, ok := d.GetOk("tags"); ok { 221 var tags []string 222 for _, tag := range raw.([]interface{}) { 223 tags = append(tags, tag.(string)) 224 } 225 req.Tags = &tags 226 } 227 } 228 229 if d.HasChange("enable_ipv6") { 230 req.EnableIPV6 = Bool(d.Get("enable_ipv6").(bool)) 231 } 232 233 if d.HasChange("dynamic_ip_required") { 234 req.DynamicIPRequired = Bool(d.Get("dynamic_ip_required").(bool)) 235 } 236 237 if d.HasChange("security_group") { 238 req.SecurityGroup = &api.ScalewaySecurityGroup{ 239 Identifier: d.Get("security_group").(string), 240 } 241 } 242 243 if err := scaleway.PatchServer(d.Id(), req); err != nil { 244 return fmt.Errorf("Failed patching scaleway server: %q", err) 245 } 246 247 return resourceScalewayServerRead(d, m) 248 } 249 250 func resourceScalewayServerDelete(d *schema.ResourceData, m interface{}) error { 251 scaleway := m.(*Client).scaleway 252 253 s, err := scaleway.GetServer(d.Id()) 254 if err != nil { 255 return err 256 } 257 258 if s.State == "stopped" { 259 return deleteStoppedServer(scaleway, s) 260 } 261 262 err = deleteRunningServer(scaleway, s) 263 264 if err == nil { 265 d.SetId("") 266 } 267 268 return err 269 }