Skip to content

Commit 33cad2e

Browse files
Laure-diCodelax
andauthored
feat(baremetal): custom partitionning (#2820)
* feat(baremetal): custom partitionning * manage file or stringJSON * code is working * add function test * manage baremetal custom partitioning schema * add updated cassettes * fix golangci-lint * delete partition_schema * update cassettes fip * Update internal/services/baremetal/server.go Co-authored-by: Jules Castéran <[email protected]> --------- Co-authored-by: Jules Castéran <[email protected]>
1 parent e712a91 commit 33cad2e

21 files changed

+17822
-255388
lines changed

internal/services/baremetal/server.go

+37-30
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package baremetal
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67

78
"github.com/hashicorp/go-cty/cty"
@@ -255,7 +256,13 @@ If this behaviour is wanted, please set 'reinstall_on_ssh_key_changes' argument
255256
},
256257
},
257258
},
259+
"partitioning": {
260+
Type: schema.TypeString,
261+
Optional: true,
262+
Description: "The partitioning schema in json format",
263+
},
258264
},
265+
259266
CustomizeDiff: customdiff.Sequence(
260267
cdf.LocalityCheck("private_network.#.id"),
261268
customDiffPrivateNetworkOption(),
@@ -313,51 +320,51 @@ func ResourceServerCreate(ctx context.Context, d *schema.ResourceData, m interfa
313320
offerID = zonal.NewID(zone, o.ID)
314321
}
315322

316-
if !d.Get("install_config_afterward").(bool) {
317-
if diags := validateInstallConfig(ctx, d, m); len(diags) > 0 {
318-
return diags
319-
}
320-
}
321-
322-
server, err := api.CreateServer(&baremetal.CreateServerRequest{
323+
req := &baremetal.CreateServerRequest{
323324
Zone: zone,
324325
Name: types.ExpandOrGenerateString(d.Get("name"), "bm"),
325326
ProjectID: types.ExpandStringPtr(d.Get("project_id")),
326327
Description: d.Get("description").(string),
327328
OfferID: offerID.ID,
328329
Tags: types.ExpandStrings(d.Get("tags")),
329-
}, scw.WithContext(ctx))
330-
if err != nil {
331-
return diag.FromErr(err)
332330
}
333331

334-
d.SetId(zonal.NewID(server.Zone, server.ID).String())
332+
partitioningSchema := baremetal.Schema{}
333+
if file, ok := d.GetOk("partitioning"); ok || !d.Get("install_config_afterward").(bool) {
334+
if diags := validateInstallConfig(ctx, d, m); len(diags) > 0 {
335+
return diags
336+
}
337+
if file != "" {
338+
todecode, _ := file.(string)
339+
err = json.Unmarshal([]byte(todecode), &partitioningSchema)
340+
if err != nil {
341+
return diag.FromErr(err)
342+
}
343+
}
344+
req.Install = &baremetal.CreateServerRequestInstall{
345+
OsID: zonal.ExpandID(d.Get("os")).ID,
346+
Hostname: d.Get("hostname").(string),
347+
SSHKeyIDs: types.ExpandStrings(d.Get("ssh_key_ids")),
348+
User: types.ExpandStringPtr(d.Get("user")),
349+
Password: types.ExpandStringPtr(d.Get("password")),
350+
PartitioningSchema: &partitioningSchema,
351+
}
352+
}
335353

336-
_, err = waitForServer(ctx, api, zone, server.ID, d.Timeout(schema.TimeoutCreate))
354+
server, err := api.CreateServer(req, scw.WithContext(ctx))
337355
if err != nil {
338356
return diag.FromErr(err)
339357
}
340358

341-
if !d.Get("install_config_afterward").(bool) {
342-
_, err = api.InstallServer(&baremetal.InstallServerRequest{
343-
Zone: server.Zone,
344-
ServerID: server.ID,
345-
OsID: zonal.ExpandID(d.Get("os")).ID,
346-
Hostname: types.ExpandStringWithDefault(d.Get("hostname"), server.Name),
347-
SSHKeyIDs: types.ExpandStrings(d.Get("ssh_key_ids")),
348-
User: types.ExpandStringPtr(d.Get("user")),
349-
Password: types.ExpandStringPtr(d.Get("password")),
350-
ServiceUser: types.ExpandStringPtr(d.Get("service_user")),
351-
ServicePassword: types.ExpandStringPtr(d.Get("service_password")),
352-
}, scw.WithContext(ctx))
353-
if err != nil {
354-
return diag.FromErr(err)
355-
}
359+
d.SetId(zonal.NewID(server.Zone, server.ID).String())
356360

361+
if d.Get("install_config_afterward").(bool) {
362+
_, err = waitForServer(ctx, api, zone, server.ID, d.Timeout(schema.TimeoutCreate))
363+
} else {
357364
_, err = waitForServerInstall(ctx, api, zone, server.ID, d.Timeout(schema.TimeoutCreate))
358-
if err != nil {
359-
return diag.FromErr(err)
360-
}
365+
}
366+
if err != nil {
367+
return diag.FromErr(err)
361368
}
362369

363370
options, optionsExist := d.GetOk("options")

internal/services/baremetal/server_test.go

+167-73
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package baremetal_test
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"reflect"
57
"regexp"
8+
"strings"
69
"testing"
710

811
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -16,8 +19,9 @@ import (
1619

1720
const SSHKeyBaremetal = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM7HUxRyQtB2rnlhQUcbDGCZcTJg7OvoznOiyC9W6IxH [email protected]"
1821

22+
var jsonConfigPartitioning = "{\"disks\":[{\"device\":\"/dev/nvme0n1\",\"partitions\":[{\"label\":\"uefi\",\"number\":1,\"size\":536870912},{\"label\":\"swap\",\"number\":2,\"size\":4294967296},{\"label\":\"boot\",\"number\":3,\"size\":1073741824},{\"label\":\"root\",\"number\":4,\"size\":1017827045376}]},{\"device\":\"/dev/nvme1n1\",\"partitions\":[{\"label\":\"swap\",\"number\":1,\"size\":4294967296},{\"label\":\"boot\",\"number\":2,\"size\":1073741824},{\"label\":\"root\",\"number\":3,\"size\":1017827045376}]}],\"filesystems\":[{\"device\":\"/dev/nvme0n1p1\",\"format\":\"fat32\",\"mountpoint\":\"/boot/efi\"},{\"device\":\"/dev/md0\",\"format\":\"ext4\",\"mountpoint\":\"/boot\"},{\"device\":\"/dev/md1\",\"format\":\"ext4\",\"mountpoint\":\"/\"}],\"raids\":[{\"devices\":[\"/dev/nvme0n1p3\",\"/dev/nvme1n1p2\"],\"level\":\"raid_level_1\",\"name\":\"/dev/md0\"},{\"devices\":[\"/dev/nvme0n1p4\",\"/dev/nvme1n1p3\"],\"level\":\"raid_level_1\",\"name\":\"/dev/md1\"}],\"zfs\":{\"pools\":[]}}"
23+
1924
func TestAccServer_Basic(t *testing.T) {
20-
// t.Skip("Skipping Baremetal Server test as no stock is available currently")
2125
tt := acctest.NewTestTools(t)
2226
defer tt.Cleanup()
2327
if !IsOfferAvailable(OfferID, Zone, tt) {
@@ -51,7 +55,7 @@ func TestAccServer_Basic(t *testing.T) {
5155
description = "test a description"
5256
offer = "%s"
5357
os = data.scaleway_baremetal_os.my_os.os_id
54-
58+
5559
tags = [ "terraform-test", "scaleway_baremetal_server", "minimal" ]
5660
ssh_key_ids = [ scaleway_iam_ssh_key.main.id ]
5761
}
@@ -172,6 +176,63 @@ func TestAccServer_WithoutInstallConfig(t *testing.T) {
172176
})
173177
}
174178

179+
func TestAccServer_CreateServerWithCustomInstallConfig(t *testing.T) {
180+
tt := acctest.NewTestTools(t)
181+
defer tt.Cleanup()
182+
if !IsOfferAvailable(OfferID, Zone, tt) {
183+
t.Skip("Offer is out of stock")
184+
}
185+
186+
SSHKeyName := "TestAccServer_CreateServerWithCustomInstallConfig"
187+
name := "TestAccServer_CreateServerWithCustomInstallConfig"
188+
189+
resource.ParallelTest(t, resource.TestCase{
190+
PreCheck: func() { acctest.PreCheck(t) },
191+
ProviderFactories: tt.ProviderFactories,
192+
CheckDestroy: baremetalchecks.CheckServerDestroy(tt),
193+
Steps: []resource.TestStep{
194+
{
195+
Config: fmt.Sprintf(`
196+
data "scaleway_baremetal_os" "my_os" {
197+
zone = "fr-par-1"
198+
name = "Ubuntu"
199+
version = "22.04 LTS (Jammy Jellyfish)"
200+
}
201+
202+
resource "scaleway_iam_ssh_key" "main" {
203+
name = "%s"
204+
public_key = "%s"
205+
}
206+
207+
resource "scaleway_baremetal_server" "base" {
208+
name = "%s"
209+
zone = "fr-par-1"
210+
description = "test a description"
211+
offer = "%s"
212+
os = data.scaleway_baremetal_os.my_os.os_id
213+
partitioning = "%s"
214+
215+
tags = [ "terraform-test", "scaleway_baremetal_server", "minimal" ]
216+
ssh_key_ids = [ scaleway_iam_ssh_key.main.id ]
217+
}
218+
`, SSHKeyName, SSHKeyBaremetal, name, OfferName, strings.ReplaceAll(jsonConfigPartitioning, "\"", "\\\"")),
219+
Check: resource.ComposeTestCheckFunc(
220+
testAccCheckBaremetalServerExists(tt, "scaleway_baremetal_server.base"),
221+
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "name", name),
222+
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "offer_id", "fr-par-1/206ea234-9097-4ae1-af68-6d2be09f47ed"),
223+
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "os", "fr-par-1/96e5f0f2-d216-4de2-8a15-68730d877885"),
224+
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "description", "test a description"),
225+
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "tags.0", "terraform-test"),
226+
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "tags.1", "scaleway_baremetal_server"),
227+
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "tags.2", "minimal"),
228+
testAccChechPartitioning(tt, "scaleway_baremetal_server.base", jsonConfigPartitioning),
229+
acctest.CheckResourceAttrUUID("scaleway_baremetal_server.base", "ssh_key_ids.0"),
230+
),
231+
},
232+
},
233+
})
234+
}
235+
175236
func TestAccServer_CreateServerWithOption(t *testing.T) {
176237
tt := acctest.NewTestTools(t)
177238
defer tt.Cleanup()
@@ -886,82 +947,82 @@ func TestAccServer_WithIPAMPrivateNetwork(t *testing.T) {
886947
},
887948
{
888949
Config: fmt.Sprintf(`
889-
resource "scaleway_vpc" "vpc01" {
890-
name = "TestAccScalewayBaremetalIPAM"
891-
}
892-
893-
resource "scaleway_vpc_private_network" "pn01" {
894-
name = "TestAccScalewayBaremetalIPAM"
895-
ipv4_subnet {
896-
subnet = "172.16.64.0/22"
897-
}
898-
vpc_id = scaleway_vpc.vpc01.id
899-
}
900-
901-
resource "scaleway_ipam_ip" "ip01" {
902-
address = "172.16.64.7"
903-
source {
904-
private_network_id = scaleway_vpc_private_network.pn01.id
905-
}
906-
}
907-
908-
resource "scaleway_ipam_ip" "ip02" {
909-
address = "172.16.64.9"
910-
source {
911-
private_network_id = scaleway_vpc_private_network.pn01.id
912-
}
913-
}
914-
915-
data "scaleway_baremetal_os" "my_os" {
916-
zone = "fr-par-1"
917-
name = "Ubuntu"
918-
version = "22.04 LTS (Jammy Jellyfish)"
919-
}
920-
921-
data "scaleway_baremetal_offer" "my_offer" {
922-
zone = "fr-par-1"
923-
name = "%s"
924-
}
925-
926-
data "scaleway_baremetal_option" "private_network" {
927-
zone = "fr-par-1"
928-
name = "Private Network"
929-
}
930-
931-
resource "scaleway_iam_ssh_key" "base" {
932-
name = "%s"
933-
public_key = "%s"
934-
}
935-
936-
resource "scaleway_baremetal_server" "base" {
937-
name = "%s"
938-
zone = "fr-par-1"
939-
offer = data.scaleway_baremetal_offer.my_offer.offer_id
940-
os = data.scaleway_baremetal_os.my_os.os_id
941-
942-
ssh_key_ids = [ scaleway_iam_ssh_key.base.id ]
943-
options {
944-
id = data.scaleway_baremetal_option.private_network.option_id
950+
resource "scaleway_vpc" "vpc01" {
951+
name = "TestAccScalewayBaremetalIPAM"
945952
}
946-
private_network {
947-
id = scaleway_vpc_private_network.pn01.id
948-
ipam_ip_ids = [scaleway_ipam_ip.ip01.id, scaleway_ipam_ip.ip02.id]
953+
954+
resource "scaleway_vpc_private_network" "pn01" {
955+
name = "TestAccScalewayBaremetalIPAM"
956+
ipv4_subnet {
957+
subnet = "172.16.64.0/22"
958+
}
959+
vpc_id = scaleway_vpc.vpc01.id
949960
}
950-
}
951-
952-
data "scaleway_ipam_ips" "base" {
953-
resource {
954-
name = scaleway_baremetal_server.base.name
955-
type = "baremetal_private_nic"
956-
}
957-
type = "ipv4"
958-
}
959-
`, OfferName, SSHKeyName, SSHKeyBaremetal, name),
961+
962+
resource "scaleway_ipam_ip" "ip01" {
963+
address = "172.16.64.7"
964+
source {
965+
private_network_id = scaleway_vpc_private_network.pn01.id
966+
}
967+
}
968+
969+
resource "scaleway_ipam_ip" "ip02" {
970+
address = "172.16.64.9"
971+
source {
972+
private_network_id = scaleway_vpc_private_network.pn01.id
973+
}
974+
}
975+
976+
data "scaleway_baremetal_os" "my_os" {
977+
zone = "fr-par-1"
978+
name = "Ubuntu"
979+
version = "22.04 LTS (Jammy Jellyfish)"
980+
}
981+
982+
data "scaleway_baremetal_offer" "my_offer" {
983+
zone = "fr-par-1"
984+
name = "%s"
985+
}
986+
987+
data "scaleway_baremetal_option" "private_network" {
988+
zone = "fr-par-1"
989+
name = "Private Network"
990+
}
991+
992+
resource "scaleway_iam_ssh_key" "base" {
993+
name = "%s"
994+
public_key = "%s"
995+
}
996+
997+
resource "scaleway_baremetal_server" "base" {
998+
name = "%s"
999+
zone = "fr-par-1"
1000+
offer = data.scaleway_baremetal_offer.my_offer.offer_id
1001+
os = data.scaleway_baremetal_os.my_os.os_id
1002+
1003+
ssh_key_ids = [ scaleway_iam_ssh_key.base.id ]
1004+
options {
1005+
id = data.scaleway_baremetal_option.private_network.option_id
1006+
}
1007+
private_network {
1008+
id = scaleway_vpc_private_network.pn01.id
1009+
ipam_ip_ids = [scaleway_ipam_ip.ip01.id, scaleway_ipam_ip.ip02.id]
1010+
}
1011+
}
1012+
1013+
data "scaleway_ipam_ips" "base" {
1014+
resource {
1015+
name = scaleway_baremetal_server.base.name
1016+
type = "baremetal_private_nic"
1017+
}
1018+
type = "ipv4"
1019+
}
1020+
`, OfferName, SSHKeyName, SSHKeyBaremetal, name),
9601021
Check: resource.ComposeTestCheckFunc(
9611022
testAccCheckBaremetalServerExists(tt, "scaleway_baremetal_server.base"),
9621023
testAccCheckBaremetalServerHasPrivateNetwork(tt, "scaleway_baremetal_server.base"),
963-
resource.TestCheckResourceAttrPair("scaleway_ipam_ip.ip01", "address", "data.scaleway_ipam_ips.base", "ips.1.address"),
964-
resource.TestCheckResourceAttrPair("scaleway_ipam_ip.ip02", "address", "data.scaleway_ipam_ips.base", "ips.0.address"),
1024+
resource.TestCheckResourceAttrPair("scaleway_ipam_ip.ip01", "address", "data.scaleway_ipam_ips.base", "ips.0.address"),
1025+
resource.TestCheckResourceAttrPair("scaleway_ipam_ip.ip02", "address", "data.scaleway_ipam_ips.base", "ips.1.address"),
9651026
),
9661027
},
9671028
},
@@ -992,6 +1053,39 @@ func testAccCheckBaremetalServerExists(tt *acctest.TestTools, n string) resource
9921053
}
9931054
}
9941055

1056+
func testAccChechPartitioning(tt *acctest.TestTools, n string, source string) resource.TestCheckFunc {
1057+
return func(s *terraform.State) error {
1058+
rs, ok := s.RootModule().Resources[n]
1059+
if !ok {
1060+
return fmt.Errorf("resource not found: %s", n)
1061+
}
1062+
baremetalAPI, zonedID, err := baremetal.NewAPIWithZoneAndID(tt.Meta, rs.Primary.ID)
1063+
if err != nil {
1064+
return err
1065+
}
1066+
1067+
server, err := baremetalAPI.GetServer(&baremetalSDK.GetServerRequest{
1068+
ServerID: zonedID.ID,
1069+
Zone: zonedID.Zone,
1070+
})
1071+
if err != nil {
1072+
return err
1073+
}
1074+
if server.Install.PartitioningSchema == nil {
1075+
return fmt.Errorf("server %s has no partitioning schema", n)
1076+
}
1077+
schema := baremetalSDK.Schema{}
1078+
err = json.Unmarshal([]byte(source), &schema)
1079+
if err != nil {
1080+
return err
1081+
}
1082+
if !reflect.DeepEqual(&schema, server.Install.PartitioningSchema) {
1083+
return fmt.Errorf("server %s has not custom partitioning install", n)
1084+
}
1085+
return nil
1086+
}
1087+
}
1088+
9951089
func testAccCheckBaremetalServerHasOptions(tt *acctest.TestTools, n string) resource.TestCheckFunc {
9961090
return func(s *terraform.State) error {
9971091
rs, ok := s.RootModule().Resources[n]

0 commit comments

Comments
 (0)