Merge pull request #1179 from zp-forks/feat/support-eco-servers

fix: support eco server lineup for ovh_dedicated_server resource
This commit is contained in:
Jérémy Dubus 2026-01-08 17:05:44 +01:00 committed by GitHub
commit 32d86a1a05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 180 additions and 4 deletions

View file

@ -91,8 +91,9 @@ resource "ovh_dedicated_server" "server" {
* `label` - (Required) Identifier of the resource
* `value` - (Required) Path to the resource in API.OVH.COM
* `service_name` - (Optional, Forces replacement) The service_name of your dedicated server. This field can be used to avoid ordering a dedicated server at creation and just create the resource using an already existing service
* `range` - (Optional) Range of the dedicated server to order. Can be `standard` or `eco`. Defaults to `standard`
~> **Note** To get the available plans, you can use the API console to first [create a cart](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#post-/order/cart) and then use the created cart ID to fetch the available plans using [the following call](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#get-/order/cart/-cartId-/baremetalServers). Once you've found the right plan, you can use [this call](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#get-/order/cart/-cartId-/baremetalServers/options) to get the available options for this plan.
~> **Note** To get the available plans, you can use the API console to first [create a cart](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#post-/order/cart) and then use the created cart ID to fetch the available plans using [the following call](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#get-/order/cart/-cartId-/baremetalServers) (or `/order/cart/{cartId}/eco` for eco servers). Once you've found the right plan, you can use [this call](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#get-/order/cart/-cartId-/baremetalServers/options) to get the available options for this plan.
### Editable fields of a dedicated server

View file

@ -472,6 +472,11 @@ func testAccPreCheckOrderDedicatedServer(t *testing.T) {
checkEnvOrSkip(t, "OVH_TESTACC_ORDER_DEDICATED_SERVER")
}
func testAccPreCheckOrderDedicatedServerEco(t *testing.T) {
testAccPreCheckCredentials(t)
checkEnvOrSkip(t, "OVH_TESTACC_ORDER_DEDICATED_SERVER_ECO")
}
func testAccPreCheckVPS(t *testing.T) {
testAccPreCheckCredentials(t)
checkEnvOrSkip(t, "OVH_VPS")

View file

@ -74,7 +74,13 @@ func (r *dedicatedServerResource) Create(ctx context.Context, req resource.Creat
// If service_name is not provided, it means dedicated server has to be ordered
if data.ServiceName.IsNull() || data.ServiceName.IsUnknown() {
order := data.ToOrder()
if err := orderCreate(order, r.config, "baremetalServers", false, defaultOrderTimeout); err != nil {
// Map the user-facing "range" attribute to the API range type.
// "standard" (default) -> "baremetalServers", "eco" -> "eco"
rangeType := "baremetalServers"
if !data.Range.IsNull() && !data.Range.IsUnknown() && data.Range.ValueString() == "eco" {
rangeType = "eco"
}
if err := orderCreate(order, r.config, rangeType, false, defaultOrderTimeout); err != nil {
resp.Diagnostics.AddError("failed to create order", err.Error())
return
}

View file

@ -376,6 +376,18 @@ func DedicatedServerResourceSchema(ctx context.Context) schema.Schema {
Description: "Defines whether the server should not be reinstalled when importing the resource",
MarkdownDescription: "Defines whether the server should not be reinstalled when importing the resource",
},
"range": schema.StringAttribute{
CustomType: ovhtypes.TfStringType{},
Optional: true,
Description: "Range of the dedicated server to order. Can be 'standard' or 'eco'. Defaults to 'standard'",
MarkdownDescription: "Range of the dedicated server to order. Can be `standard` or `eco`. Defaults to `standard`",
Validators: []validator.String{
stringvalidator.OneOf(
"standard",
"eco",
),
},
},
"region": schema.StringAttribute{
CustomType: ovhtypes.TfStringType{},
Computed: true,
@ -719,6 +731,7 @@ type DedicatedServerModel struct {
Rack ovhtypes.TfStringValue `tfsdk:"rack" json:"rack"`
PreventInstallOnCreate ovhtypes.TfBoolValue `tfsdk:"prevent_install_on_create" json:"-"`
PreventInstallOnImport ovhtypes.TfBoolValue `tfsdk:"prevent_install_on_import" json:"-"`
Range ovhtypes.TfStringValue `tfsdk:"range" json:"-"`
Region ovhtypes.TfStringValue `tfsdk:"region" json:"region"`
RescueMail ovhtypes.TfStringValue `tfsdk:"rescue_mail" json:"rescueMail"`
RescueSshKey ovhtypes.TfStringValue `tfsdk:"rescue_ssh_key" json:"rescueSshKey"`
@ -838,6 +851,10 @@ func (v *DedicatedServerModel) MergeWith(other *DedicatedServerModel) {
v.PreventInstallOnImport = other.PreventInstallOnImport
}
if (v.Range.IsUnknown() || v.Range.IsNull()) && !other.Range.IsUnknown() {
v.Range = other.Range
}
if (v.Region.IsUnknown() || v.Region.IsNull()) && !other.Region.IsUnknown() {
v.Region = other.Region
}

View file

@ -136,7 +136,153 @@ func TestAccDedicatedServer_basic(t *testing.T) {
ImportStateVerify: true,
ImportStateVerifyIdentifierAttribute: "service_name",
ImportStateVerifyIgnore: []string{
"display_name", "order", "ovh_subsidiary", "plan", "plan_option",
"display_name", "order", "ovh_subsidiary", "plan", "plan_option", "range",
},
ImportStateIdFunc: func(s *terraform.State) (string, error) {
service, ok := s.RootModule().Resources["ovh_dedicated_server.server"]
if !ok {
return "", errors.New("ovh_dedicated_server.server not found")
}
return service.Primary.Attributes["service_name"], nil
},
},
},
})
}
func dedicatedServerEcoResourceTestConfig(updated bool) string {
var (
monitoring = true
noIntervention = false
operatingSystem = "debian11_64"
displayName = "First display name"
efiBootloaderPath = ""
)
if updated {
monitoring = false
noIntervention = true
operatingSystem = "debian12_64"
displayName = "Second display name"
efiBootloaderPath = `\\efi\\debian\\grubx64.efi`
}
return fmt.Sprintf(`
data "ovh_me" "account" {}
resource "ovh_dedicated_server" "server" {
ovh_subsidiary = data.ovh_me.account.ovh_subsidiary
range = "eco"
monitoring = %t
no_intervention = %t
os = "%s"
display_name = "%s"
efi_bootloader_path = "%s"
plan = [
{
plan_code = "24sys012"
duration = "P1M"
pricing_mode = "default"
configuration = [
{
label = "dedicated_datacenter"
value = "rbx"
},
{
label = "dedicated_os"
value = "none_64.en"
},
{
label = "region"
value = "europe"
}
]
}
]
plan_option = [
{
duration = "P1M"
plan_code = "softraid-2x512nvme-24sys"
pricing_mode = "default"
quantity = 1
},
{
duration = "P1M"
plan_code = "vrack-bandwidth-500-24sys"
pricing_mode = "default"
quantity = 1
},
{
duration = "P1M"
plan_code = "bandwidth-1000-24sys"
pricing_mode = "default"
quantity = 1
},
{
duration = "P1M"
plan_code = "ram-32g-ecc-2666-24sys"
pricing_mode = "default"
quantity = 1
}
]
}
`, monitoring, noIntervention, operatingSystem, displayName, efiBootloaderPath)
}
func TestAccDedicatedServer_eco(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheckOrderDedicatedServerEco(t)
},
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: dedicatedServerEcoResourceTestConfig(false),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "monitoring", "true"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "no_intervention", "false"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "display_name", "First display name"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "iam.display_name", "First display name"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "os", "debian11_64"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "efi_bootloader_path", ""),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "range", "eco"),
),
},
{
Config: dedicatedServerEcoResourceTestConfig(true),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "monitoring", "false"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "no_intervention", "true"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "display_name", "Second display name"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "iam.display_name", "Second display name"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "os", "debian12_64"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "efi_bootloader_path", "\\efi\\debian\\grubx64.efi"),
resource.TestCheckResourceAttr(
"ovh_dedicated_server.server", "range", "eco"),
),
},
{
ResourceName: "ovh_dedicated_server.server",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIdentifierAttribute: "service_name",
ImportStateVerifyIgnore: []string{
"display_name", "order", "ovh_subsidiary", "plan", "plan_option", "range",
},
ImportStateIdFunc: func(s *terraform.State) (string, error) {
service, ok := s.RootModule().Resources["ovh_dedicated_server.server"]

View file

@ -38,8 +38,9 @@ Use this resource to order and manage a dedicated server.
* `label` - (Required) Identifier of the resource
* `value` - (Required) Path to the resource in API.OVH.COM
* `service_name` - (Optional, Forces replacement) The service_name of your dedicated server. This field can be used to avoid ordering a dedicated server at creation and just create the resource using an already existing service
* `range` - (Optional) Range of the dedicated server to order. Can be `standard` or `eco`. Defaults to `standard`
~> **Note** To get the available plans, you can use the API console to first [create a cart](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#post-/order/cart) and then use the created cart ID to fetch the available plans using [the following call](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#get-/order/cart/-cartId-/baremetalServers). Once you've found the right plan, you can use [this call](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#get-/order/cart/-cartId-/baremetalServers/options) to get the available options for this plan.
~> **Note** To get the available plans, you can use the API console to first [create a cart](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#post-/order/cart) and then use the created cart ID to fetch the available plans using [the following call](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#get-/order/cart/-cartId-/baremetalServers) (or `/order/cart/{cartId}/eco` for eco servers). Once you've found the right plan, you can use [this call](https://eu.api.ovh.com/console/?section=%2Forder&branch=v1#get-/order/cart/-cartId-/baremetalServers/options) to get the available options for this plan.
### Editable fields of a dedicated server