Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 37 additions & 30 deletions internal/services/baremetal/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package baremetal

import (
"context"
"encoding/json"
"fmt"

"github.com/hashicorp/go-cty/cty"
Expand Down Expand Up @@ -255,7 +256,13 @@ If this behaviour is wanted, please set 'reinstall_on_ssh_key_changes' argument
},
},
},
"partitioning": {
Type: schema.TypeString,
Optional: true,
Description: "The path to the patitioning json file",
},
},

CustomizeDiff: customdiff.Sequence(
cdf.LocalityCheck("private_network.#.id"),
customDiffPrivateNetworkOption(),
Expand Down Expand Up @@ -313,51 +320,51 @@ func ResourceServerCreate(ctx context.Context, d *schema.ResourceData, m interfa
offerID = zonal.NewID(zone, o.ID)
}

if !d.Get("install_config_afterward").(bool) {
if diags := validateInstallConfig(ctx, d, m); len(diags) > 0 {
return diags
}
}

server, err := api.CreateServer(&baremetal.CreateServerRequest{
req := &baremetal.CreateServerRequest{
Zone: zone,
Name: types.ExpandOrGenerateString(d.Get("name"), "bm"),
ProjectID: types.ExpandStringPtr(d.Get("project_id")),
Description: d.Get("description").(string),
OfferID: offerID.ID,
Tags: types.ExpandStrings(d.Get("tags")),
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

d.SetId(zonal.NewID(server.Zone, server.ID).String())
partitioningSchema := baremetal.Schema{}
if file, ok := d.GetOk("partitioning"); ok || !d.Get("install_config_afterward").(bool) {
if diags := validateInstallConfig(ctx, d, m); len(diags) > 0 {
return diags
}
if file != "" {
todecode, _ := file.(string)
err = json.Unmarshal([]byte(todecode), &partitioningSchema)
if err != nil {
return diag.FromErr(err)
}
}
req.Install = &baremetal.CreateServerRequestInstall{
OsID: zonal.ExpandID(d.Get("os")).ID,
Hostname: d.Get("hostname").(string),
SSHKeyIDs: types.ExpandStrings(d.Get("ssh_key_ids")),
User: types.ExpandStringPtr(d.Get("user")),
Password: types.ExpandStringPtr(d.Get("password")),
PartitioningSchema: &partitioningSchema,
}
}

_, err = waitForServer(ctx, api, zone, server.ID, d.Timeout(schema.TimeoutCreate))
server, err := api.CreateServer(req, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

if !d.Get("install_config_afterward").(bool) {
_, err = api.InstallServer(&baremetal.InstallServerRequest{
Zone: server.Zone,
ServerID: server.ID,
OsID: zonal.ExpandID(d.Get("os")).ID,
Hostname: types.ExpandStringWithDefault(d.Get("hostname"), server.Name),
SSHKeyIDs: types.ExpandStrings(d.Get("ssh_key_ids")),
User: types.ExpandStringPtr(d.Get("user")),
Password: types.ExpandStringPtr(d.Get("password")),
ServiceUser: types.ExpandStringPtr(d.Get("service_user")),
ServicePassword: types.ExpandStringPtr(d.Get("service_password")),
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}
d.SetId(zonal.NewID(server.Zone, server.ID).String())

if d.Get("install_config_afterward").(bool) {
_, err = waitForServer(ctx, api, zone, server.ID, d.Timeout(schema.TimeoutCreate))
} else {
_, err = waitForServerInstall(ctx, api, zone, server.ID, d.Timeout(schema.TimeoutCreate))
if err != nil {
return diag.FromErr(err)
}
}
if err != nil {
return diag.FromErr(err)
}

options, optionsExist := d.GetOk("options")
Expand Down
240 changes: 167 additions & 73 deletions internal/services/baremetal/server_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package baremetal_test

import (
"encoding/json"
"fmt"
"reflect"
"regexp"
"strings"
"testing"

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

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

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\":[]}}"

func TestAccServer_Basic(t *testing.T) {
// t.Skip("Skipping Baremetal Server test as no stock is available currently")
tt := acctest.NewTestTools(t)
defer tt.Cleanup()
if !IsOfferAvailable(OfferID, Zone, tt) {
Expand Down Expand Up @@ -51,7 +55,7 @@ func TestAccServer_Basic(t *testing.T) {
description = "test a description"
offer = "%s"
os = data.scaleway_baremetal_os.my_os.os_id

tags = [ "terraform-test", "scaleway_baremetal_server", "minimal" ]
ssh_key_ids = [ scaleway_iam_ssh_key.main.id ]
}
Expand Down Expand Up @@ -172,6 +176,63 @@ func TestAccServer_WithoutInstallConfig(t *testing.T) {
})
}

func TestAccServer_CreateServerWithCustomInstallConfig(t *testing.T) {
tt := acctest.NewTestTools(t)
defer tt.Cleanup()
if !IsOfferAvailable(OfferID, Zone, tt) {
t.Skip("Offer is out of stock")
}

SSHKeyName := "TestAccServer_CreateServerWithCustomInstallConfig"
name := "TestAccServer_CreateServerWithCustomInstallConfig"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: baremetalchecks.CheckServerDestroy(tt),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
data "scaleway_baremetal_os" "my_os" {
zone = "fr-par-1"
name = "Ubuntu"
version = "22.04 LTS (Jammy Jellyfish)"
}

resource "scaleway_iam_ssh_key" "main" {
name = "%s"
public_key = "%s"
}

resource "scaleway_baremetal_server" "base" {
name = "%s"
zone = "fr-par-1"
description = "test a description"
offer = "%s"
os = data.scaleway_baremetal_os.my_os.os_id
partitioning = "%s"

tags = [ "terraform-test", "scaleway_baremetal_server", "minimal" ]
ssh_key_ids = [ scaleway_iam_ssh_key.main.id ]
}
`, SSHKeyName, SSHKeyBaremetal, name, OfferName, strings.ReplaceAll(jsonConfigPartitioning, "\"", "\\\"")),
Check: resource.ComposeTestCheckFunc(
testAccCheckBaremetalServerExists(tt, "scaleway_baremetal_server.base"),
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "name", name),
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "offer_id", "fr-par-1/206ea234-9097-4ae1-af68-6d2be09f47ed"),
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "os", "fr-par-1/96e5f0f2-d216-4de2-8a15-68730d877885"),
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "description", "test a description"),
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "tags.0", "terraform-test"),
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "tags.1", "scaleway_baremetal_server"),
resource.TestCheckResourceAttr("scaleway_baremetal_server.base", "tags.2", "minimal"),
testAccChechPartitioning(tt, "scaleway_baremetal_server.base", jsonConfigPartitioning),
acctest.CheckResourceAttrUUID("scaleway_baremetal_server.base", "ssh_key_ids.0"),
),
},
},
})
}

func TestAccServer_CreateServerWithOption(t *testing.T) {
tt := acctest.NewTestTools(t)
defer tt.Cleanup()
Expand Down Expand Up @@ -886,82 +947,82 @@ func TestAccServer_WithIPAMPrivateNetwork(t *testing.T) {
},
{
Config: fmt.Sprintf(`
resource "scaleway_vpc" "vpc01" {
name = "TestAccScalewayBaremetalIPAM"
}

resource "scaleway_vpc_private_network" "pn01" {
name = "TestAccScalewayBaremetalIPAM"
ipv4_subnet {
subnet = "172.16.64.0/22"
}
vpc_id = scaleway_vpc.vpc01.id
}

resource "scaleway_ipam_ip" "ip01" {
address = "172.16.64.7"
source {
private_network_id = scaleway_vpc_private_network.pn01.id
}
}

resource "scaleway_ipam_ip" "ip02" {
address = "172.16.64.9"
source {
private_network_id = scaleway_vpc_private_network.pn01.id
}
}

data "scaleway_baremetal_os" "my_os" {
zone = "fr-par-1"
name = "Ubuntu"
version = "22.04 LTS (Jammy Jellyfish)"
}

data "scaleway_baremetal_offer" "my_offer" {
zone = "fr-par-1"
name = "%s"
}

data "scaleway_baremetal_option" "private_network" {
zone = "fr-par-1"
name = "Private Network"
}

resource "scaleway_iam_ssh_key" "base" {
name = "%s"
public_key = "%s"
}

resource "scaleway_baremetal_server" "base" {
name = "%s"
zone = "fr-par-1"
offer = data.scaleway_baremetal_offer.my_offer.offer_id
os = data.scaleway_baremetal_os.my_os.os_id

ssh_key_ids = [ scaleway_iam_ssh_key.base.id ]
options {
id = data.scaleway_baremetal_option.private_network.option_id
resource "scaleway_vpc" "vpc01" {
name = "TestAccScalewayBaremetalIPAM"
}
private_network {
id = scaleway_vpc_private_network.pn01.id
ipam_ip_ids = [scaleway_ipam_ip.ip01.id, scaleway_ipam_ip.ip02.id]

resource "scaleway_vpc_private_network" "pn01" {
name = "TestAccScalewayBaremetalIPAM"
ipv4_subnet {
subnet = "172.16.64.0/22"
}
vpc_id = scaleway_vpc.vpc01.id
}
}

data "scaleway_ipam_ips" "base" {
resource {
name = scaleway_baremetal_server.base.name
type = "baremetal_private_nic"
}
type = "ipv4"
}
`, OfferName, SSHKeyName, SSHKeyBaremetal, name),

resource "scaleway_ipam_ip" "ip01" {
address = "172.16.64.7"
source {
private_network_id = scaleway_vpc_private_network.pn01.id
}
}

resource "scaleway_ipam_ip" "ip02" {
address = "172.16.64.9"
source {
private_network_id = scaleway_vpc_private_network.pn01.id
}
}

data "scaleway_baremetal_os" "my_os" {
zone = "fr-par-1"
name = "Ubuntu"
version = "22.04 LTS (Jammy Jellyfish)"
}

data "scaleway_baremetal_offer" "my_offer" {
zone = "fr-par-1"
name = "%s"
}

data "scaleway_baremetal_option" "private_network" {
zone = "fr-par-1"
name = "Private Network"
}

resource "scaleway_iam_ssh_key" "base" {
name = "%s"
public_key = "%s"
}

resource "scaleway_baremetal_server" "base" {
name = "%s"
zone = "fr-par-1"
offer = data.scaleway_baremetal_offer.my_offer.offer_id
os = data.scaleway_baremetal_os.my_os.os_id

ssh_key_ids = [ scaleway_iam_ssh_key.base.id ]
options {
id = data.scaleway_baremetal_option.private_network.option_id
}
private_network {
id = scaleway_vpc_private_network.pn01.id
ipam_ip_ids = [scaleway_ipam_ip.ip01.id, scaleway_ipam_ip.ip02.id]
}
}

data "scaleway_ipam_ips" "base" {
resource {
name = scaleway_baremetal_server.base.name
type = "baremetal_private_nic"
}
type = "ipv4"
}
`, OfferName, SSHKeyName, SSHKeyBaremetal, name),
Check: resource.ComposeTestCheckFunc(
testAccCheckBaremetalServerExists(tt, "scaleway_baremetal_server.base"),
testAccCheckBaremetalServerHasPrivateNetwork(tt, "scaleway_baremetal_server.base"),
resource.TestCheckResourceAttrPair("scaleway_ipam_ip.ip01", "address", "data.scaleway_ipam_ips.base", "ips.1.address"),
resource.TestCheckResourceAttrPair("scaleway_ipam_ip.ip02", "address", "data.scaleway_ipam_ips.base", "ips.0.address"),
resource.TestCheckResourceAttrPair("scaleway_ipam_ip.ip01", "address", "data.scaleway_ipam_ips.base", "ips.0.address"),
resource.TestCheckResourceAttrPair("scaleway_ipam_ip.ip02", "address", "data.scaleway_ipam_ips.base", "ips.1.address"),
),
},
},
Expand Down Expand Up @@ -992,6 +1053,39 @@ func testAccCheckBaremetalServerExists(tt *acctest.TestTools, n string) resource
}
}

func testAccChechPartitioning(tt *acctest.TestTools, n string, source string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("resource not found: %s", n)
}
baremetalAPI, zonedID, err := baremetal.NewAPIWithZoneAndID(tt.Meta, rs.Primary.ID)
if err != nil {
return err
}

server, err := baremetalAPI.GetServer(&baremetalSDK.GetServerRequest{
ServerID: zonedID.ID,
Zone: zonedID.Zone,
})
if err != nil {
return err
}
if server.Install.PartitioningSchema == nil {
return fmt.Errorf("server %s has no partitioning schema", n)
}
schema := baremetalSDK.Schema{}
err = json.Unmarshal([]byte(source), &schema)
if err != nil {
return err
}
if !reflect.DeepEqual(&schema, server.Install.PartitioningSchema) {
return fmt.Errorf("server %s has not custom partitioning install", n)
}
return nil
}
}

func testAccCheckBaremetalServerHasOptions(tt *acctest.TestTools, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down
Loading
Loading