Skip to content

Commit 7a17d88

Browse files
authored
Merge branch 'master' into patch-1
2 parents acfac02 + 8f95b60 commit 7a17d88

File tree

13 files changed

+8129
-1813
lines changed

13 files changed

+8129
-1813
lines changed

.github/workflows/announce.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ jobs:
1010
steps:
1111
- name: Get tag
1212
id: get_tag
13-
run: echo "{TAG}=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
13+
run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
1414
- name: Get version
1515
id: get_version
16-
run: echo "{VERSION}=${TAG##v}" >> $GITHUB_OUTPUT
16+
run: echo "VERSION=${TAG##v}" >> $GITHUB_OUTPUT
1717
env:
1818
TAG: ${{ steps.get_tag.outputs.TAG }}
1919
- name: Prepare message
2020
id: get_message
21-
run: echo "{MSG}=${{ secrets.SLACK_MESSAGE }}" >> $GITHUB_OUTPUT
21+
run: echo "MSG=${{ secrets.SLACK_MESSAGE }}" >> $GITHUB_OUTPUT
2222
env:
2323
VERSION: ${{ steps.get_version.outputs.VERSION }}
2424
TAG: ${{ steps.get_tag.outputs.TAG }}

docs/data-sources/instance_server.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ attached to the server.
6363

6464
- `enable_dynamic_ip` - True if dynamic IP in enable on the server.
6565

66-
- `routed_ip_enabled` - True if the server support routed ip only.
67-
6866
- `state` - The state of the server. Possible values are: `started`, `stopped` or `standby`.
6967

7068
- `cloud_init` - The cloud init script associated with this server.

docs/data-sources/instance_servers.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ In addition to all above arguments, the following attributes are exported:
6060
- `ipv6_address` - The default ipv6 address routed to the server. ( Only set when enable_ipv6 is set to true )
6161
- `ipv6_gateway` - The ipv6 gateway address. ( Only set when enable_ipv6 is set to true )
6262
- `ipv6_prefix_length` - The prefix length of the ipv6 subnet routed to the server. ( Only set when enable_ipv6 is set to true )
63-
- `routed_ip_enabled` - True if the server support routed ip only.
6463
- `enable_dynamic_ip` - If true a dynamic IP will be attached to the server.
6564
- `image` - The UUID or the label of the base image used by the server.
6665
- `placement_group_id` - The [placement group](https://developers.scaleway.com/en/products/instance/api/#placement-groups-d8f653) the server is attached to.

docs/resources/baremetal_server.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,47 @@ resource "scaleway_baremetal_server" "base" {
226226
227227
```
228228

229+
### Migrate from hourly to monthly plan
230+
231+
To migrate from an hourly to a monthly subscription for a Scaleway Baremetal server, it is important to understand that the migration can only be done by using the data source.
232+
You cannot directly modify the subscription_period of an existing scaleway_baremetal_offer resource. Instead, you must define the monthly offer using the data source and then update the server configuration accordingly.
233+
234+
#### Hourly Plan Example
235+
236+
```terraform
237+
data "scaleway_baremetal_offer" "my_offer" {
238+
zone = "fr-par-1"
239+
name = "EM-B220E-NVME"
240+
subscription_period = "hourly"
241+
}
242+
243+
resource "scaleway_baremetal_server" "server01" {
244+
name = "UpdateSubscriptionPeriod"
245+
offer = data.scaleway_baremetal_offer.my_offer.offer_id
246+
zone = "%s"
247+
install_config_afterward = true
248+
}
249+
```
250+
251+
#### Monthly Plan Example
252+
253+
```terraform
254+
data "scaleway_baremetal_offer" "my_offer" {
255+
zone = "fr-par-1"
256+
name = "EM-B220E-NVME"
257+
subscription_period = "monthly"
258+
}
259+
260+
resource "scaleway_baremetal_server" "server01" {
261+
name = "UpdateSubscriptionPeriod"
262+
offer = data.scaleway_baremetal_offer.my_offer.offer_id
263+
zone = "fr-par-1"
264+
install_config_afterward = true
265+
}
266+
```
267+
268+
**Important** Once you migrate to a monthly subscription, you cannot downgrade back to an hourly plan. Ensure that the monthly plan meets your needs before making the switch.
269+
229270
## Argument Reference
230271

231272
The following arguments are supported:

docs/resources/instance_server.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ attached to the server. Updates to this field will trigger a stop/start of the s
227227

228228
~> **Important:** If this field contains local volumes, you have to first detach them, in one apply, and then delete the volume in another apply.
229229

230-
- `enable_ipv6` - (Defaults to `false`) Determines if IPv6 is enabled for the server. Useful only with `routed_ip_enabled` as false, otherwise ipv6 is always supported.
230+
- `enable_ipv6` - (Defaults to `false`) Determines if IPv6 is enabled for the server.
231231
Deprecated: Please use a scaleway_instance_ip with a `routed_ipv6` type.
232232

233233
- `ip_id` - (Optional) The ID of the reserved IP that is attached to the server.
@@ -238,10 +238,6 @@ attached to the server. Updates to this field will trigger a stop/start of the s
238238

239239
- `enable_dynamic_ip` - (Defaults to `false`) If true a dynamic IP will be attached to the server.
240240

241-
- `routed_ip_enabled` - (Defaults to `true`) If true, the server will support routed ips only. Changing it to true will migrate the server and its IP to routed type.
242-
243-
~> **Important:** Enabling routed ip will restart the server
244-
245241
- `state` - (Defaults to `started`) The state of the server. Possible values are: `started`, `stopped` or `standby`.
246242

247243
- `user_data` - (Optional) The user data associated with the server.

internal/services/baremetal/helpers.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import (
1212
"github.com/scaleway/scaleway-sdk-go/api/baremetal/v1"
1313
baremetalV3 "github.com/scaleway/scaleway-sdk-go/api/baremetal/v3"
1414
"github.com/scaleway/scaleway-sdk-go/scw"
15+
"github.com/scaleway/scaleway-sdk-go/validation"
1516
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
1617
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
18+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
1719
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
1820
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
1921
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
@@ -224,3 +226,51 @@ func privateNetworkSetHash(v interface{}) int {
224226

225227
return schema.HashString(buf.String())
226228
}
229+
230+
func getOfferInformations(ctx context.Context, offer interface{}, id string, i interface{}) (*baremetal.Offer, error) {
231+
api, zone, err := NewAPIWithZoneAndID(i, id)
232+
if err != nil {
233+
return nil, err
234+
}
235+
236+
if validation.IsUUID(regional.ExpandID(offer.(string)).ID) {
237+
offerID := regional.ExpandID(offer.(string))
238+
239+
return FindOfferByID(ctx, api, zone.Zone, offerID.ID)
240+
} else {
241+
return api.GetOfferByName(&baremetal.GetOfferByNameRequest{
242+
OfferName: offer.(string),
243+
Zone: zone.Zone,
244+
})
245+
}
246+
}
247+
248+
func customDiffOffer() func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
249+
return func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
250+
if diff.Get("offer") == "" || !diff.HasChange("offer") || diff.Id() == "" {
251+
return nil
252+
}
253+
254+
oldOffer, newOffer := diff.GetChange("offer")
255+
256+
oldOfferInfo, err := getOfferInformations(ctx, oldOffer, diff.Id(), i)
257+
if err != nil {
258+
return errors.New(err.Error())
259+
}
260+
261+
newOfferInfo, err := getOfferInformations(ctx, newOffer, diff.Id(), i)
262+
if err != nil {
263+
return errors.New(err.Error())
264+
}
265+
266+
if oldOfferInfo.Name != newOfferInfo.Name {
267+
return diff.ForceNew("offer")
268+
}
269+
270+
if oldOfferInfo.SubscriptionPeriod == baremetal.OfferSubscriptionPeriodMonthly && newOfferInfo.SubscriptionPeriod == baremetal.OfferSubscriptionPeriodHourly {
271+
return errors.New("invalid plan transition: you cannot transition from a monthly plan to an hourly plan. Only the reverse (hourly to monthly) is supported. Please update your configuration accordingly")
272+
}
273+
274+
return nil
275+
}
276+
}

internal/services/baremetal/server.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/scaleway/terraform-provider-scaleway/v2/internal/dsf"
1919
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
2020
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
21+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
2122
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
2223
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
2324
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
@@ -54,10 +55,10 @@ func ResourceServer() *schema.Resource {
5455
Description: "Hostname of the server",
5556
},
5657
"offer": {
57-
Type: schema.TypeString,
58-
Required: true,
59-
ForceNew: true,
60-
Description: "ID or name of the server offer",
58+
Type: schema.TypeString,
59+
Required: true,
60+
Description: "ID or name of the server offer",
61+
ValidateDiagFunc: verify.IsUUIDOrNameOffer(),
6162
DiffSuppressFunc: func(_, oldValue, newValue string, d *schema.ResourceData) bool {
6263
// remove the locality from the IDs when checking diff
6364
if locality.ExpandID(newValue) == locality.ExpandID(oldValue) {
@@ -68,7 +69,6 @@ func ResourceServer() *schema.Resource {
6869

6970
return ok && newValue == offerName
7071
},
71-
ValidateDiagFunc: verify.IsUUIDOrNameOffer(),
7272
},
7373
"offer_id": {
7474
Type: schema.TypeString,
@@ -264,8 +264,8 @@ If this behaviour is wanted, please set 'reinstall_on_ssh_key_changes' argument
264264
Description: "The partitioning schema in json format",
265265
},
266266
},
267-
268267
CustomizeDiff: customdiff.Sequence(
268+
customDiffOffer(),
269269
cdf.LocalityCheck("private_network.#.id"),
270270
customDiffPrivateNetworkOption(),
271271
),
@@ -529,6 +529,26 @@ func ResourceServerUpdate(ctx context.Context, d *schema.ResourceData, m interfa
529529
var serverGetOptionIDs []*baremetal.ServerOption
530530
serverGetOptionIDs = append(serverGetOptionIDs, server.Options...)
531531

532+
if d.HasChange("offer") {
533+
ServerID := regional.ExpandID(server.ID)
534+
535+
_, err = api.MigrateServerToMonthlyOffer(&baremetal.MigrateServerToMonthlyOfferRequest{
536+
Zone: zonedID.Zone,
537+
ServerID: ServerID.ID,
538+
}, scw.WithContext(ctx))
539+
if err != nil {
540+
return diag.FromErr(err)
541+
}
542+
543+
_, err := api.WaitForServer(&baremetal.WaitForServerRequest{
544+
Zone: zonedID.Zone,
545+
ServerID: ServerID.ID,
546+
})
547+
if err != nil {
548+
return diag.FromErr(err)
549+
}
550+
}
551+
532552
if d.HasChange("options") {
533553
options, err := expandOptions(d.Get("options"))
534554
if err != nil {

internal/services/baremetal/server_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,100 @@ func TestAccServer_WithIPAMPrivateNetwork(t *testing.T) {
10391039
})
10401040
}
10411041

1042+
func TestAccServer_UpdateSubscriptionPeriod(t *testing.T) {
1043+
tt := acctest.NewTestTools(t)
1044+
defer tt.Cleanup()
1045+
1046+
newOffer := "EM-B320E-NVME"
1047+
1048+
if !IsOfferAvailable(OfferID, Zone, tt) {
1049+
t.Skip("Offer is out of stock")
1050+
}
1051+
1052+
resource.ParallelTest(t, resource.TestCase{
1053+
PreCheck: func() { acctest.PreCheck(t) },
1054+
ProviderFactories: tt.ProviderFactories,
1055+
CheckDestroy: resource.ComposeTestCheckFunc(
1056+
baremetalchecks.CheckServerDestroy(tt),
1057+
),
1058+
Steps: []resource.TestStep{
1059+
{
1060+
Config: fmt.Sprintf(`
1061+
data "scaleway_baremetal_offer" "my_offer" {
1062+
zone = "%s"
1063+
name = "%s"
1064+
subscription_period = "hourly"
1065+
}
1066+
1067+
resource "scaleway_baremetal_server" "server01" {
1068+
name = "TestAccServer_UpdateSubscriptionPeriod"
1069+
offer = data.scaleway_baremetal_offer.my_offer.offer_id
1070+
zone = "%s"
1071+
install_config_afterward = true
1072+
}`, Zone, OfferName, Zone),
1073+
Check: resource.ComposeTestCheckFunc(
1074+
resource.TestCheckResourceAttr("scaleway_baremetal_server.server01", "zone", Zone),
1075+
resource.TestCheckResourceAttrPair("scaleway_baremetal_server.server01", "offer_id", "data.scaleway_baremetal_offer.my_offer", "offer_id"),
1076+
),
1077+
},
1078+
{
1079+
Config: fmt.Sprintf(`
1080+
data "scaleway_baremetal_offer" "my_offer" {
1081+
zone = "%s"
1082+
name = "%s"
1083+
subscription_period = "monthly"
1084+
}
1085+
1086+
resource "scaleway_baremetal_server" "server01" {
1087+
name = "TestAccServer_UpdateSubscriptionPeriod"
1088+
offer = data.scaleway_baremetal_offer.my_offer.offer_id
1089+
zone = "%s"
1090+
install_config_afterward = true
1091+
}`, Zone, OfferName, Zone),
1092+
Check: resource.ComposeTestCheckFunc(
1093+
resource.TestCheckResourceAttr("scaleway_baremetal_server.server01", "zone", Zone),
1094+
resource.TestCheckResourceAttrPair("scaleway_baremetal_server.server01", "offer_id", "data.scaleway_baremetal_offer.my_offer", "offer_id"),
1095+
),
1096+
},
1097+
{
1098+
Config: fmt.Sprintf(`
1099+
data "scaleway_baremetal_offer" "my_offer" {
1100+
zone = "%s"
1101+
name = "%s"
1102+
subscription_period = "hourly"
1103+
}
1104+
1105+
resource "scaleway_baremetal_server" "server01" {
1106+
name = "TestAccServer_UpdateSubscriptionPeriod"
1107+
offer = data.scaleway_baremetal_offer.my_offer.offer_id
1108+
zone = "%s"
1109+
install_config_afterward = true
1110+
}`, Zone, OfferName, Zone),
1111+
ExpectError: regexp.MustCompile(`invalid plan transition: you cannot transition from a monthly plan to an hourly plan. Only the reverse \(hourly to monthly\) is supported. Please update your configuration accordingly`),
1112+
},
1113+
{
1114+
Config: fmt.Sprintf(`
1115+
data "scaleway_baremetal_offer" "my_offer" {
1116+
zone = "%s"
1117+
name = "%s"
1118+
subscription_period = "hourly"
1119+
}
1120+
1121+
resource "scaleway_baremetal_server" "server01" {
1122+
name = "Test_UpdateSubscriptionPeriod"
1123+
offer = data.scaleway_baremetal_offer.my_offer.offer_id
1124+
zone = "%s"
1125+
install_config_afterward = true
1126+
}`, Zone, newOffer, Zone),
1127+
Check: resource.ComposeTestCheckFunc(
1128+
resource.TestCheckResourceAttr("scaleway_baremetal_server.server01", "zone", "fr-par-1"),
1129+
resource.TestCheckResourceAttrPair("scaleway_baremetal_server.server01", "offer_id", "data.scaleway_baremetal_offer.my_offer", "offer_id"),
1130+
),
1131+
},
1132+
},
1133+
})
1134+
}
1135+
10421136
func testAccCheckBaremetalServerExists(tt *acctest.TestTools, n string) resource.TestCheckFunc {
10431137
return func(s *terraform.State) error {
10441138
rs, ok := s.RootModule().Resources[n]

0 commit comments

Comments
 (0)