provider/scaleway server volume property (#9695)
* provider/scaleway: extract volume validation helpers * provider/scaleway: add server volume property fixes #9499 * provider/scaleway: update `scaleway_server` docu * provider/scaleway: fix volume handling this actually broken when merging the latest SDK update :( * provider/scaleway: fix volume attachment * provider/scaleway: fix volume expectation
This commit is contained in:
parent
18b3736ba4
commit
98d84680b7
|
@ -18,6 +18,22 @@ func String(val string) *string {
|
|||
return &val
|
||||
}
|
||||
|
||||
func validateVolumeType(v interface{}, k string) (ws []string, errors []error) {
|
||||
value := v.(string)
|
||||
if value != "l_ssd" {
|
||||
errors = append(errors, fmt.Errorf("%q must be l_ssd", k))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func validateVolumeSize(v interface{}, k string) (ws []string, errors []error) {
|
||||
value := v.(int)
|
||||
if value < 1 || value > 150 {
|
||||
errors = append(errors, fmt.Errorf("%q be more than 1 and less than 150", k))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// deleteRunningServer terminates the server and waits until it is removed.
|
||||
func deleteRunningServer(scaleway *api.ScalewayAPI, server *api.ScalewayServer) error {
|
||||
err := scaleway.PostServerAction(server.Identifier, "terminate")
|
||||
|
|
|
@ -57,6 +57,29 @@ func resourceScalewayServer() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"volume": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"size_in_gb": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validateVolumeSize,
|
||||
},
|
||||
"type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validateVolumeType,
|
||||
},
|
||||
"volume_id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"private_ip": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
|
@ -97,6 +120,28 @@ func resourceScalewayServerCreate(d *schema.ResourceData, m interface{}) error {
|
|||
server.Bootscript = String(bootscript.(string))
|
||||
}
|
||||
|
||||
if vs, ok := d.GetOk("volume"); ok {
|
||||
server.Volumes = make(map[string]string)
|
||||
|
||||
volumes := vs.([]interface{})
|
||||
for i, v := range volumes {
|
||||
volume := v.(map[string]interface{})
|
||||
|
||||
volumeID, err := scaleway.PostVolume(api.ScalewayVolumeDefinition{
|
||||
Size: uint64(volume["size_in_gb"].(int)) * gb,
|
||||
Type: volume["type"].(string),
|
||||
Name: fmt.Sprintf("%s-%d", server.Name, volume["size_in_gb"].(int)),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
volume["volume_id"] = volumeID
|
||||
volumes[i] = volume
|
||||
server.Volumes[fmt.Sprintf("%d", i+1)] = volumeID
|
||||
}
|
||||
d.Set("volume", volumes)
|
||||
}
|
||||
|
||||
if raw, ok := d.GetOk("tags"); ok {
|
||||
for _, tag := range raw.([]interface{}) {
|
||||
server.Tags = append(server.Tags, tag.(string))
|
||||
|
|
|
@ -31,6 +31,39 @@ func TestAccScalewayServer_Basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccScalewayServer_Volumes(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckScalewayServerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccCheckScalewayServerVolumeConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckScalewayServerExists("scaleway_server.base"),
|
||||
testAccCheckScalewayServerAttributes("scaleway_server.base"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"scaleway_server.base", "type", "C1"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"scaleway_server.base", "volume.#", "2"),
|
||||
resource.TestCheckResourceAttrSet(
|
||||
"scaleway_server.base", "volume.0.volume_id"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"scaleway_server.base", "volume.0.type", "l_ssd"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"scaleway_server.base", "volume.0.size_in_gb", "20"),
|
||||
resource.TestCheckResourceAttrSet(
|
||||
"scaleway_server.base", "volume.1.volume_id"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"scaleway_server.base", "volume.1.type", "l_ssd"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"scaleway_server.base", "volume.1.size_in_gb", "30"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccScalewayServer_SecurityGroup(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
|
@ -161,6 +194,25 @@ resource "scaleway_server" "base" {
|
|||
tags = [ "terraform-test" ]
|
||||
}`, armImageIdentifier)
|
||||
|
||||
var testAccCheckScalewayServerVolumeConfig = fmt.Sprintf(`
|
||||
resource "scaleway_server" "base" {
|
||||
name = "test"
|
||||
# ubuntu 14.04
|
||||
image = "%s"
|
||||
type = "C1"
|
||||
tags = [ "terraform-test" ]
|
||||
|
||||
volume {
|
||||
size_in_gb = 20
|
||||
type = "l_ssd"
|
||||
}
|
||||
|
||||
volume {
|
||||
size_in_gb = 30
|
||||
type = "l_ssd"
|
||||
}
|
||||
}`, armImageIdentifier)
|
||||
|
||||
var testAccCheckScalewayServerConfig_SecurityGroup = fmt.Sprintf(`
|
||||
resource "scaleway_security_group" "blue" {
|
||||
name = "blue"
|
||||
|
|
|
@ -26,26 +26,14 @@ func resourceScalewayVolume() *schema.Resource {
|
|||
Required: true,
|
||||
},
|
||||
"size_in_gb": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
||||
value := v.(int)
|
||||
if value < 1 || value > 150 {
|
||||
errors = append(errors, fmt.Errorf("%q be more than 1 and less than 150", k))
|
||||
}
|
||||
return
|
||||
},
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validateVolumeSize,
|
||||
},
|
||||
"type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
||||
value := v.(string)
|
||||
if value != "l_ssd" {
|
||||
errors = append(errors, fmt.Errorf("%q must be l_ssd", k))
|
||||
}
|
||||
return
|
||||
},
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validateVolumeType,
|
||||
},
|
||||
"server": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
|
@ -88,8 +76,8 @@ func resourceScalewayVolumeRead(d *schema.ResourceData, m interface{}) error {
|
|||
return err
|
||||
}
|
||||
d.Set("name", volume.Name)
|
||||
if size, ok := volume.Size.(uint64); ok {
|
||||
d.Set("size_in_gb", size/gb)
|
||||
if size, ok := volume.Size.(float64); ok {
|
||||
d.Set("size_in_gb", uint64(size)/gb)
|
||||
}
|
||||
d.Set("type", volume.VolumeType)
|
||||
d.Set("server", "")
|
||||
|
|
|
@ -69,7 +69,7 @@ func resourceScalewayVolumeAttachmentCreate(d *schema.ResourceData, m interface{
|
|||
|
||||
// the API request requires most volume attributes to be unset to succeed
|
||||
for k, v := range volumes {
|
||||
v.Size = 0
|
||||
v.Size = nil
|
||||
v.CreationDate = ""
|
||||
v.Organization = ""
|
||||
v.ModificationDate = ""
|
||||
|
@ -174,7 +174,7 @@ func resourceScalewayVolumeAttachmentDelete(d *schema.ResourceData, m interface{
|
|||
|
||||
// the API request requires most volume attributes to be unset to succeed
|
||||
for k, v := range volumes {
|
||||
v.Size = 0
|
||||
v.Size = nil
|
||||
v.CreationDate = ""
|
||||
v.Organization = ""
|
||||
v.ModificationDate = ""
|
||||
|
|
|
@ -60,7 +60,7 @@ func testAccCheckScalewayVolumeAttributes(n string) resource.TestCheckFunc {
|
|||
if volume.Name != "test" {
|
||||
return fmt.Errorf("volume has wrong name: %q", volume.Name)
|
||||
}
|
||||
if volume.Size != 2000000000 {
|
||||
if volume.Size != 2e+09 {
|
||||
return fmt.Errorf("volume has wrong size: %d", volume.Size)
|
||||
}
|
||||
if volume.VolumeType != "l_ssd" {
|
||||
|
|
|
@ -17,7 +17,12 @@ For additional details please refer to [API documentation](https://developer.sca
|
|||
resource "scaleway_server" "test" {
|
||||
name = "test"
|
||||
image = "5faef9cd-ea9b-4a63-9171-9e26bec03dbc"
|
||||
type = "C1"
|
||||
type = "VC1M"
|
||||
|
||||
volume {
|
||||
size_in_gb = 20
|
||||
type = "l_ssd"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -36,6 +41,16 @@ The following arguments are supported:
|
|||
|
||||
Field `name`, `type`, `tags`, `dynamic_ip_required`, `security_group` are editable.
|
||||
|
||||
## Volume
|
||||
|
||||
You can attach additional volumes to your instance, which will share the lifetime
|
||||
of your `scaleway_server` resource.
|
||||
|
||||
The `volume` mapping supports the following:
|
||||
|
||||
* `type` - (Required) The type of volume. Can be `"l_ssd"`
|
||||
* `size_in_gb` - (Required) The size of the volume in gigabytes.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
|
Loading…
Reference in New Issue