Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
44 changes: 31 additions & 13 deletions internal/services/instance/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/scaleway/terraform-provider-scaleway/v2/internal/cdf"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/dsf"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/identity"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
Expand Down Expand Up @@ -58,6 +59,7 @@ func ResourceServer() *schema.Resource {
},
SchemaVersion: 0,
SchemaFunc: serverSchema,
Identity: identity.DefaultZonal(),
CustomizeDiff: customdiff.All(
cdf.LocalityCheck(
"placement_group_id",
Expand Down Expand Up @@ -86,6 +88,11 @@ func serverSchema() map[string]*schema.Schema {
DiffSuppressFunc: dsf.Locality,
ExactlyOneOf: []string{"image", "root_volume.0.volume_id"},
},
"computed_image_id": {
Type: schema.TypeString,
Computed: true,
Description: "The computed UUID of the base image used by the server",
},
"type": {
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -516,7 +523,10 @@ func ResourceInstanceServerCreate(ctx context.Context, d *schema.ResourceData, m
return diag.FromErr(err)
}

d.SetId(zonal.NewID(zone, res.Server.ID).String())
err = identity.SetZonalIdentity(d, res.Server.Zone, res.Server.ID)
if err != nil {
return diag.FromErr(err)
}

_, err = waitForServer(ctx, api.API, zone, res.Server.ID, d.Timeout(schema.TimeoutCreate))
if err != nil {
Expand Down Expand Up @@ -646,16 +656,10 @@ func ResourceInstanceServerCreate(ctx context.Context, d *schema.ResourceData, m
}
}

return append(diags, ResourceInstanceServerRead(ctx, d, m)...)
return append(diags, setServerState(ctx, d, m, api, res.Server.Zone, res.Server.ID)...)
}

//gocyclo:ignore
func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
api, zone, id, err := instancehelpers.InstanceAndBlockAPIWithZoneAndID(m, d.Id())
if err != nil {
return diag.FromErr(err)
}

func setServerState(ctx context.Context, d *schema.ResourceData, m any, api *instancehelpers.BlockAndInstanceAPI, zone scw.Zone, id string) diag.Diagnostics {
server, err := waitForServer(ctx, api.API, zone, id, d.Timeout(schema.TimeoutRead))
if err != nil {
if errorCheck(err, "is not found") {
Expand All @@ -668,9 +672,6 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m a
return diag.FromErr(err)
}

////
// Read Server
////
state, err := serverStateFlatten(server.State)
if err != nil {
return diag.FromErr(err)
Expand Down Expand Up @@ -702,6 +703,8 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m a
_ = d.Set("image", zonal.NewID(zone, server.Image.ID).String())
}

_ = d.Set("computed_image_id", server.Image.ID)

if server.PlacementGroup != nil {
_ = d.Set("placement_group_id", zonal.NewID(zone, server.PlacementGroup.ID).String())
_ = d.Set("placement_group_policy_respected", server.PlacementGroup.PolicyRespected)
Expand Down Expand Up @@ -893,6 +896,21 @@ You can check the full list of compatible server types:
return diags
}

//gocyclo:ignore
func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
api, zone, id, err := instancehelpers.InstanceAndBlockAPIWithZoneAndID(m, d.Id())
if err != nil {
return diag.FromErr(err)
}

err = identity.SetZonalIdentity(d, zone, id)
if err != nil {
return diag.FromErr(err)
}

return setServerState(ctx, d, m, api, zone, id)
}

//gocyclo:ignore
func ResourceInstanceServerUpdate(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
api, zone, id, err := instancehelpers.InstanceAndBlockAPIWithZoneAndID(m, d.Id())
Expand Down Expand Up @@ -1171,7 +1189,7 @@ func ResourceInstanceServerUpdate(ctx context.Context, d *schema.ResourceData, m
return diag.FromErr(err)
}

return append(warnings, ResourceInstanceServerRead(ctx, d, m)...)
return append(warnings, setServerState(ctx, d, m, api, zone, id)...)
}

func ResourceInstanceServerDelete(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
Expand Down
7 changes: 4 additions & 3 deletions internal/services/instance/server_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/datasource"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/instance/instancehelpers"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
)
Expand Down Expand Up @@ -36,7 +37,7 @@ func DataSourceServer() *schema.Resource {
}

func DataSourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
instanceAPI, zone, err := newAPIWithZone(d, m)
api, zone, id, err := instancehelpers.InstanceAndBlockAPIWithZoneAndID(m, d.Id())
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -45,7 +46,7 @@ func DataSourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m
if !ok {
serverName := d.Get("name").(string)

res, err := instanceAPI.ListServers(&instance.ListServersRequest{
res, err := api.API.ListServers(&instance.ListServersRequest{
Zone: zone,
Name: types.ExpandStringPtr(serverName),
Project: types.ExpandStringPtr(d.Get("project_id")),
Expand All @@ -70,5 +71,5 @@ func DataSourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m
d.SetId(zonedID)
_ = d.Set("server_id", zonedID)

return ResourceInstanceServerRead(ctx, d, m)
return setServerState(ctx, d, m, api, zone, id)
}
170 changes: 170 additions & 0 deletions internal/services/instance/server_image_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package instance_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
instancechecks "github.com/scaleway/terraform-provider-scaleway/v2/internal/services/instance/testfuncs"
)

func TestAccServer_CustomDiffImage(t *testing.T) {
tt := acctest.NewTestTools(t)
defer tt.Cleanup()

var mainServerID, controlServerID string

resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: tt.ProviderFactories,
CheckDestroy: instancechecks.IsServerDestroyed(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_instance_server" "main" {
name = "tf-acc-server-custom-diff-image-main-server"
image = "ubuntu_jammy"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "scaleway_instance_server", "custom_diff_image", "main" ]
}
resource "scaleway_instance_server" "control" {
name = "tf-acc-server-custom-diff-image-control-server"
image = "ubuntu_jammy"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "scaleway_instance_server", "custom_diff_image", "control" ]
}
`,
Check: resource.ComposeTestCheckFunc(
instancechecks.IsServerPresent(tt, "scaleway_instance_server.main"),
instancechecks.IsServerPresent(tt, "scaleway_instance_server.control"),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "image", "ubuntu_jammy"),
resource.TestCheckResourceAttr("scaleway_instance_server.control", "image", "ubuntu_jammy"),
acctest.CheckResourceIDPersisted("scaleway_instance_server.main", &mainServerID),
acctest.CheckResourceIDPersisted("scaleway_instance_server.control", &controlServerID),
),
},
{
Config: fmt.Sprintf(`
data "scaleway_marketplace_image" "jammy" {
label = "ubuntu_jammy"
image_type = "%s"
}
resource "scaleway_instance_server" "main" {
name = "tf-acc-server-custom-diff-image-main-server"
image = data.scaleway_marketplace_image.jammy.id
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "scaleway_instance_server", "custom_diff_image", "main" ]
}
resource "scaleway_instance_server" "control" {
name = "tf-acc-server-custom-diff-image-control-server"
image = "ubuntu_jammy"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "scaleway_instance_server", "custom_diff_image", "control" ]
}
`, marketplaceImageType),
Check: resource.ComposeTestCheckFunc(
instancechecks.IsServerPresent(tt, "scaleway_instance_server.main"),
instancechecks.IsServerPresent(tt, "scaleway_instance_server.control"),
resource.TestCheckResourceAttrPair("scaleway_instance_server.main", "image", "data.scaleway_marketplace_image.jammy", "id"),
resource.TestCheckResourceAttr("scaleway_instance_server.control", "image", "ubuntu_jammy"),
imageIDMatchLabel(tt, "scaleway_instance_server.main", "scaleway_instance_server.control", true),
acctest.CheckResourceIDPersisted("scaleway_instance_server.main", &mainServerID),
acctest.CheckResourceIDPersisted("scaleway_instance_server.control", &controlServerID),
),
},
{
Config: fmt.Sprintf(`
data "scaleway_marketplace_image" "focal" {
label = "ubuntu_focal"
image_type = "%s"
}
resource "scaleway_instance_server" "main" {
name = "tf-acc-server-custom-diff-image-main-server"
image = data.scaleway_marketplace_image.focal.id
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "scaleway_instance_server", "custom_diff_image", "main" ]
}
resource "scaleway_instance_server" "control" {
name = "tf-acc-server-custom-diff-image-control-server"
image = "ubuntu_jammy"
type = "DEV1-S"
state = "stopped"
tags = [ "terraform-test", "scaleway_instance_server", "custom_diff_image", "control" ]
}
`, marketplaceImageType),
Check: resource.ComposeTestCheckFunc(
instancechecks.IsServerPresent(tt, "scaleway_instance_server.main"),
instancechecks.IsServerPresent(tt, "scaleway_instance_server.control"),
resource.TestCheckResourceAttrPair("scaleway_instance_server.main", "image", "data.scaleway_marketplace_image.focal", "id"),
resource.TestCheckResourceAttr("scaleway_instance_server.control", "image", "ubuntu_jammy"),
imageIDMatchLabel(tt, "scaleway_instance_server.main", "scaleway_instance_server.control", false),
acctest.CheckResourceIDChanged("scaleway_instance_server.main", &mainServerID),
acctest.CheckResourceIDPersisted("scaleway_instance_server.control", &controlServerID),
),
},
},
})
}

func TestAccServer_ImageFromMarketplaceDataSource(t *testing.T) {
tt := acctest.NewTestTools(t)
defer tt.Cleanup()

resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: tt.ProviderFactories,
Steps: []resource.TestStep{
{
Config: `
data "scaleway_marketplace_image" "local" {
label = "ubuntu_focal"
instance_type = "DEV1-S"
}

resource "scaleway_instance_server" "main" {
name = "tf-acc-server-image-from-marketplace-datasource"
image = "${data.scaleway_marketplace_image.local.id}"
type = "DEV1-S"
}`,
Check: resource.ComposeTestCheckFunc(
instancechecks.DoesImageExists(tt, "data.scaleway_marketplace_image.local"),
resource.TestCheckResourceAttr("data.scaleway_marketplace_image.local", "label", "ubuntu_focal"),
resource.TestCheckResourceAttr("data.scaleway_marketplace_image.local", "image_type", "instance_local"),
resource.TestCheckResourceAttr("data.scaleway_marketplace_image.local", "instance_type", "DEV1-S"),
resource.TestCheckResourceAttrPair("data.scaleway_marketplace_image.local", "id", "scaleway_instance_server.main", "image"),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "root_volume.0.volume_type", "l_ssd"),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "image", "fr-par-1/"+ubuntuFocalLocalFrPar1ImageID),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "computed_image_id", ubuntuFocalLocalFrPar1ImageID),
),
},
{
Config: `
data "scaleway_marketplace_image" "sbs" {
label = "ubuntu_focal"
instance_type = "DEV1-S"
image_type = "instance_sbs"
}

resource "scaleway_instance_server" "main" {
name = "tf-acc-server-image-from-marketplace-datasource"
image = "${data.scaleway_marketplace_image.sbs.id}"
type = "DEV1-S"
}`,
Check: resource.ComposeTestCheckFunc(
instancechecks.DoesImageExists(tt, "data.scaleway_marketplace_image.sbs"),
resource.TestCheckResourceAttr("data.scaleway_marketplace_image.sbs", "label", "ubuntu_focal"),
resource.TestCheckResourceAttr("data.scaleway_marketplace_image.sbs", "image_type", "instance_sbs"),
resource.TestCheckResourceAttr("data.scaleway_marketplace_image.sbs", "instance_type", "DEV1-S"),
resource.TestCheckResourceAttrPair("data.scaleway_marketplace_image.sbs", "id", "scaleway_instance_server.main", "image"),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "root_volume.0.volume_type", "sbs_volume"),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "image", "fr-par-1/"+ubuntuFocalSBSFrPar1ImageID),
resource.TestCheckResourceAttr("scaleway_instance_server.main", "computed_image_id", ubuntuFocalSBSFrPar1ImageID),
),
},
},
})
}
Loading