From bac7fc966fceaf5af337e99210fa1472b3271bd4 Mon Sep 17 00:00:00 2001 From: cguran-ionos Date: Mon, 28 Oct 2024 16:03:09 +0200 Subject: [PATCH] feature: add hostname to server and vcpu_server, cube_server, and servers ds (#697) --- CHANGELOG.md | 7 ++++ docs/data-sources/cube_server.md | 1 + docs/data-sources/server.md | 1 + docs/data-sources/vcpu_server.md | 1 + docs/resources/cube_server.md | 5 ++- docs/resources/server.md | 3 +- docs/resources/vcpu_server.md | 1 + docs/resources/volume.md | 2 +- ionoscloud/data_source_cube_server.go | 9 ++++ ionoscloud/data_source_server.go | 10 ++++- ionoscloud/data_source_servers.go | 6 ++- ionoscloud/data_source_vcpu_server.go | 4 ++ ionoscloud/import_s3_keys_test.go | 2 +- ionoscloud/resource_cube_server.go | 37 ++++++++++++++--- ionoscloud/resource_cube_server_test.go | 41 ++++++++++-------- ionoscloud/resource_server.go | 22 +++++++++- ionoscloud/resource_server_test.go | 13 ++++-- ionoscloud/resource_vcpu_server.go | 6 +++ ionoscloud/resource_vcpu_server_test.go | 5 +++ ionoscloud/resource_volume.go | 4 +- ionoscloud/test_constants.go | 55 ++++++++++++++----------- utils/constant/constants.go | 1 + 22 files changed, 174 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 846249385..a84bbf2a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 6.6.1 + +### Features +- Add `hostname` to `ionoscloud_server` resource and data source +- Add `hostname` to `ionoscloud_vcpu_server` resource and data source +- Add `hostname` to `ionoscloud_cube_server` resource and data source + ## 6.6.0 ### Refactor - Rename `S3` occurrences to `Object Storage` diff --git a/docs/data-sources/cube_server.md b/docs/data-sources/cube_server.md index 8d5930b8a..a32f4696b 100644 --- a/docs/data-sources/cube_server.md +++ b/docs/data-sources/cube_server.md @@ -46,6 +46,7 @@ The following attributes are returned by the datasource: * `template_uuid` - The UUID of the template for creating a CUBE server; the available templates for CUBE servers can be found on the templates resource * `id` - The id of that resource * `name` - The name of that resource +* `hostname` - The hostname of the server * `type` - Server usages: CUBE * `vm_state`- Status of the virtual Machine * `datacenter_id` - The id of the datacenter diff --git a/docs/data-sources/server.md b/docs/data-sources/server.md index ef14310fb..c000a63c8 100644 --- a/docs/data-sources/server.md +++ b/docs/data-sources/server.md @@ -44,6 +44,7 @@ data "ionoscloud_server" "example" { The following attributes are returned by the datasource: * `template_uuid` - The UUID of the template for creating a CUBE server; the available templates for CUBE servers can be found on the templates resource +* `hostname` - The hostname of the resource. * `id` - The id of that resource * `name` - The name of that resource * `type` - Server usages: [ENTERPRISE](https://docs.ionos.com/cloud/compute-engine/virtual-servers/virtual-servers) or [CUBE](https://docs.ionos.com/cloud/compute-engine/virtual-servers/cloud-cubes) diff --git a/docs/data-sources/vcpu_server.md b/docs/data-sources/vcpu_server.md index c47328723..bcc7ed3d3 100644 --- a/docs/data-sources/vcpu_server.md +++ b/docs/data-sources/vcpu_server.md @@ -45,6 +45,7 @@ The following attributes are returned by the datasource: * `id` - The id of that resource * `name` - The name of that resource +* `hostname` - The hostname of the server * `type` - The type of the server, should always be `VCPU` * `vm_state`- Status of the virtual Machine * `datacenter_id` - The id of the datacenter diff --git a/docs/resources/cube_server.md b/docs/resources/cube_server.md index 075efa4d7..f077e9179 100644 --- a/docs/resources/cube_server.md +++ b/docs/resources/cube_server.md @@ -19,7 +19,7 @@ This resource will create an operational server. After this section completes, t ```hcl data "ionoscloud_template" "example" { - name = "CUBES XS" + name = "Basic Cube XS" } resource "ionoscloud_datacenter" "example" { @@ -62,7 +62,7 @@ resource "random_password" "server_image_password" { ```hcl data "ionoscloud_template" "example" { - name = "CUBES XS" + name = "Basic Cube XS" } resource "ionoscloud_datacenter" "example" { name = "Datacenter Example" @@ -120,6 +120,7 @@ resource "random_password" "server_image_password" { - `template_uuid` - (Required)[string] The UUID of the template for creating a CUBE server; the available templates for CUBE servers can be found on the templates resource - `name` - (Required)[string] The name of the server. - `datacenter_id` - (Required)[string] The ID of a Virtual Data Center. +- `hostname` - The hostname of the resource. Allowed characters are a-z, 0-9 and - (minus). Hostname should not start with minus and should not be longer than 63 characters. - `image_name` - (Optional)[string] The name, ID or alias of the image. May also be a snapshot ID. It is required if `licence_type` is not provided. Attribute is immutable. - `availability_zone` - (Optional)[string] The availability zone in which the server should exist. This property is immutable. - `licence_type` - (Optional)[string] Sets the OS type of the server. diff --git a/docs/resources/server.md b/docs/resources/server.md index 06aba19a3..d593d0ed2 100644 --- a/docs/resources/server.md +++ b/docs/resources/server.md @@ -170,7 +170,7 @@ resource "random_password" "server_image_password" { ```hcl data "ionoscloud_template" "example" { - name = "CUBES XS" + name = "Basic Cube XS" } resource "ionoscloud_datacenter" "example" { @@ -261,6 +261,7 @@ resource "ionoscloud_server" "test" { - `template_uuid` - (Optional)[string] The UUID of the template for creating a CUBE server; the available templates for CUBE servers can be found on the templates resource - `name` - (Required)[string] The name of the server. - `datacenter_id` - (Required)[string] The ID of a Virtual Data Center. +- `hostname` - (Optional)[string] The hostname of the resource. Allowed characters are a-z, 0-9 and - (minus). Hostname should not start with minus and should not be longer than 63 characters. - `cores` - (Optional)(Computed)[integer] Number of server CPU cores. - `ram` - (Optional)(Computed)[integer] The amount of memory for the server in MB. - `image_name` - (Optional)[string] The name, ID or alias of the image. May also be a snapshot ID. It is required if `licence_type` is not provided. Attribute is immutable. diff --git a/docs/resources/vcpu_server.md b/docs/resources/vcpu_server.md index 74f1d0f5f..eb0661173 100644 --- a/docs/resources/vcpu_server.md +++ b/docs/resources/vcpu_server.md @@ -95,6 +95,7 @@ resource "random_password" "server_image_password" { - `name` - (Required)[string] The name of the server. - `datacenter_id` - (Required)[string] The ID of a Virtual Data Center. +- `hostname` - (Optional)[string] The hostname of the resource. Allowed characters are a-z, 0-9 and - (minus). Hostname should not start with minus and should not be longer than 63 characters. - `cores` - (Optional)[integer] Number of server CPU cores. - `ram` - (Optional)[integer] The amount of memory for the server in MB. - `image_name` - (Optional)[string] The name, ID or alias of the image. May also be a snapshot ID. It is required if `licence_type` is not provided. Attribute is immutable. diff --git a/docs/resources/volume.md b/docs/resources/volume.md index 3184b2626..8e313a80b 100644 --- a/docs/resources/volume.md +++ b/docs/resources/volume.md @@ -93,7 +93,7 @@ resource "ionoscloud_volume" "example" { user_data = "foo" } -resource "ionoscloud_volume" "example" { +resource "ionoscloud_volume" "example2" { datacenter_id = ionoscloud_datacenter.example.id server_id = ionoscloud_server.example.id name = "Another Volume Example" diff --git a/ionoscloud/data_source_cube_server.go b/ionoscloud/data_source_cube_server.go index b5cf99a4c..900e98f25 100644 --- a/ionoscloud/data_source_cube_server.go +++ b/ionoscloud/data_source_cube_server.go @@ -37,6 +37,10 @@ func dataSourceCubeServer() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, "availability_zone": { Type: schema.TypeString, Computed: true, @@ -201,6 +205,11 @@ func setCubeServerData(d *schema.ResourceData, server *ionoscloud.Server, token return err } } + if server.Properties.Hostname != nil { + if err := d.Set("hostname", *server.Properties.Hostname); err != nil { + return err + } + } if server.Properties.Cores != nil { if err := d.Set("cores", *server.Properties.Cores); err != nil { return err diff --git a/ionoscloud/data_source_server.go b/ionoscloud/data_source_server.go index 1e1dca7a3..42f1e4f18 100644 --- a/ionoscloud/data_source_server.go +++ b/ionoscloud/data_source_server.go @@ -34,6 +34,10 @@ func dataSourceServer() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, "type": { Type: schema.TypeString, Optional: true, @@ -240,7 +244,11 @@ func setServerData(d *schema.ResourceData, server *ionoscloud.Server, token *ion return err } } - + if server.Properties.Hostname != nil { + if err := d.Set("hostname", *server.Properties.Hostname); err != nil { + return err + } + } if server.Properties.Cores != nil { if err := d.Set("cores", *server.Properties.Cores); err != nil { return err diff --git a/ionoscloud/data_source_servers.go b/ionoscloud/data_source_servers.go index 2b327e2a2..fa96b4776 100644 --- a/ionoscloud/data_source_servers.go +++ b/ionoscloud/data_source_servers.go @@ -47,7 +47,10 @@ func dataSourceServers() *schema.Resource { Type: schema.TypeString, Optional: true, }, - + "hostname": { + Type: schema.TypeString, + Computed: true, + }, "cores": { Type: schema.TypeInt, Computed: true, @@ -368,6 +371,7 @@ func SetServerProperties(server ionoscloud.Server) map[string]interface{} { if server.Properties != nil { utils.SetPropWithNilCheck(serverMap, "template_uuid", server.Properties.TemplateUuid) utils.SetPropWithNilCheck(serverMap, "name", server.Properties.Name) + utils.SetPropWithNilCheck(serverMap, "hostname", server.Properties.Hostname) utils.SetPropWithNilCheck(serverMap, "cores", server.Properties.Cores) utils.SetPropWithNilCheck(serverMap, "ram", server.Properties.Ram) utils.SetPropWithNilCheck(serverMap, "availability_zone", server.Properties.AvailabilityZone) diff --git a/ionoscloud/data_source_vcpu_server.go b/ionoscloud/data_source_vcpu_server.go index 3d74bc4cb..3264de52a 100644 --- a/ionoscloud/data_source_vcpu_server.go +++ b/ionoscloud/data_source_vcpu_server.go @@ -22,6 +22,10 @@ func dataSourceVCPUServer() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, "type": { Type: schema.TypeString, Computed: true, diff --git a/ionoscloud/import_s3_keys_test.go b/ionoscloud/import_s3_keys_test.go index 64eac4b1c..03f13ae67 100644 --- a/ionoscloud/import_s3_keys_test.go +++ b/ionoscloud/import_s3_keys_test.go @@ -16,7 +16,7 @@ func TestAccKeyImportBasic(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesInternal(t, &testAccProvider), - CheckDestroy: testAccChecks3KeyDestroyCheck, + CheckDestroy: testAccChecksKeyDestroyCheck, Steps: []resource.TestStep{ { Config: testAccImportS3KeyConfigBasic, diff --git a/ionoscloud/resource_cube_server.go b/ionoscloud/resource_cube_server.go index 0bc89e240..4556ae595 100644 --- a/ionoscloud/resource_cube_server.go +++ b/ionoscloud/resource_cube_server.go @@ -44,6 +44,12 @@ func resourceCubeServer() *schema.Resource { Required: true, ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotWhiteSpace), }, + "hostname": { + Type: schema.TypeString, + Optional: true, + Description: "The hostname of the resource. Allowed characters are a-z, 0-9 and - (minus). Hostname should not start with minus and should not be longer than 63 characters.", + ValidateDiagFunc: validation.ToDiagFunc(validation.All(validation.StringIsNotWhiteSpace, validation.StringLenBetween(1, 63))), + }, "availability_zone": { Type: schema.TypeString, Optional: true, @@ -395,6 +401,13 @@ func resourceCubeServerCreate(ctx context.Context, d *schema.ResourceData, meta serverType := constant.CubeType server.Properties.Type = &serverType + if v, ok := d.GetOk("hostname"); ok { + if v.(string) != "" { + vStr := v.(string) + server.Properties.Hostname = &vStr + } + } + if _, ok := d.GetOk("boot_cdrom"); ok { resId := d.Get("boot_cdrom").(string) server.Properties.BootCdrom = &ionoscloud.ResourceReference{ @@ -430,29 +443,24 @@ func resourceCubeServerCreate(ctx context.Context, d *schema.ResourceData, meta } else { volume.ImageAlias = nil } - if backupUnitID, ok := d.GetOk("volume.0.backup_unit_id"); ok { if utils.IsValidUUID(backupUnitID.(string)) { if image == "" && imageAlias == "" { diags := diag.FromErr(fmt.Errorf("it is mandatory to provide either public image or imageAlias in conjunction with backup unit id property")) return diags } - backupUnitID := backupUnitID.(string) volume.BackupunitId = &backupUnitID } } - if userData, ok := d.GetOk("volume.0.user_data"); ok { if image == "" && imageAlias == "" { diags := diag.FromErr(fmt.Errorf("it is mandatory to provide either public image or imageAlias that has cloud-init compatibility in conjunction with backup unit id property ")) return diags } - userData := userData.(string) volume.UserData = &userData } - server.Entities = &ionoscloud.ServerEntities{ Volumes: &ionoscloud.AttachedVolumes{ Items: &[]ionoscloud.Volume{ @@ -635,6 +643,13 @@ func resourceCubeServerRead(ctx context.Context, d *schema.ResourceData, meta in } } + if server.Properties.Hostname != nil { + if err := d.Set("hostname", *server.Properties.Hostname); err != nil { + diags := diag.FromErr(err) + return diags + } + } + if server.Properties.AvailabilityZone != nil { if err := d.Set("availability_zone", *server.Properties.AvailabilityZone); err != nil { diags := diag.FromErr(err) @@ -787,6 +802,12 @@ func resourceCubeServerUpdate(ctx context.Context, d *schema.ResourceData, meta request.Name = &nStr } + if d.HasChange("hostname") { + _, n := d.GetChange("hostname") + nStr := n.(string) + request.Hostname = &nStr + } + if d.HasChange("boot_cdrom") { _, n := d.GetChange("boot_cdrom") bootCdrom := n.(string) @@ -1091,7 +1112,11 @@ func resourceCubeServerImport(ctx context.Context, d *schema.ResourceData, meta return nil, fmt.Errorf("error setting name %w", err) } } - + if server.Properties.Hostname != nil { + if err := d.Set("hostname", *server.Properties.Hostname); err != nil { + return nil, fmt.Errorf("error setting hostname %w", err) + } + } if server.Properties.Name != nil { if err := d.Set("template_uuid", *server.Properties.TemplateUuid); err != nil { return nil, fmt.Errorf("error setting template uuid %w", err) diff --git a/ionoscloud/resource_cube_server_test.go b/ionoscloud/resource_cube_server_test.go index 2cce4b595..f9c334848 100644 --- a/ionoscloud/resource_cube_server_test.go +++ b/ionoscloud/resource_cube_server_test.go @@ -36,6 +36,7 @@ func TestAccCubeServerBasic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCubeServerExists(constant.ServerCubeResource+"."+constant.ServerTestResource, &server), resource.TestCheckResourceAttr(constant.ServerCubeResource+"."+constant.ServerTestResource, "name", constant.ServerTestResource), + resource.TestCheckResourceAttr(constant.ServerCubeResource+"."+constant.ServerTestResource, "hostname", constant.ServerTestHostname), resource.TestCheckResourceAttr(constant.ServerCubeResource+"."+constant.ServerTestResource, "availability_zone", "AUTO"), utils.TestImageNotNull(constant.ServerCubeResource, "boot_image"), resource.TestCheckResourceAttrPair(constant.ServerCubeResource+"."+constant.ServerTestResource, "image_password", constant.RandomPassword+".server_image_password", "result"), @@ -65,6 +66,7 @@ func TestAccCubeServerBasic(t *testing.T) { Config: testAccDataSourceCubeServerMatchId, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceById, "name", constant.ServerCubeResource+"."+constant.ServerTestResource, "name"), + resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceById, "hostname", constant.ServerCubeResource+"."+constant.ServerTestResource, "hostname"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceById, "availability_zone", constant.ServerCubeResource+"."+constant.ServerTestResource, "availability_zone"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceById, "type", constant.ServerCubeResource+"."+constant.ServerTestResource, "type"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceById, "volumes.0.name", constant.ServerCubeResource+"."+constant.ServerTestResource, "volume.0.name"), @@ -93,6 +95,7 @@ func TestAccCubeServerBasic(t *testing.T) { Config: testAccDataSourceCubeServerMatchName, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceByName, "name", constant.ServerCubeResource+"."+constant.ServerTestResource, "name"), + resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceByName, "hostname", constant.ServerCubeResource+"."+constant.ServerTestResource, "hostname"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceByName, "availability_zone", constant.ServerCubeResource+"."+constant.ServerTestResource, "availability_zone"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceByName, "type", constant.ServerCubeResource+"."+constant.ServerTestResource, "type"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerCubeResource+"."+constant.ServerDataSourceByName, "volumes.0.name", constant.ServerCubeResource+"."+constant.ServerTestResource, "volume.0.name"), @@ -126,6 +129,7 @@ func TestAccCubeServerBasic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCubeServerExists(constant.ServerCubeResource+"."+constant.ServerTestResource, &server), resource.TestCheckResourceAttr(constant.ServerCubeResource+"."+constant.ServerTestResource, "name", constant.UpdatedResources), + resource.TestCheckResourceAttr(constant.ServerCubeResource+"."+constant.ServerTestResource, "hostname", "updatedhostname"), resource.TestCheckResourceAttr(constant.ServerCubeResource+"."+constant.ServerTestResource, "availability_zone", "AUTO"), utils.TestImageNotNull(constant.ServerCubeResource, "boot_image"), resource.TestCheckResourceAttrPair(constant.ServerCubeResource+"."+constant.ServerTestResource, "image_password", constant.RandomPassword+".server_image_password_updated", "result"), @@ -403,10 +407,10 @@ func testAccCheckCubeServerExists(n string, server *ionoscloud.Server) resource. const testAccCheckCubeServerConfigUpdate = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" + name = "Basic Cube XS" cores = 1 - ram = 1024 - storage_size = 30 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { @@ -426,6 +430,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerCubeResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.UpdatedResources + `" + hostname = "updatedhostname" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id availability_zone = "AUTO" image_name ="ubuntu:latest" @@ -480,10 +485,10 @@ data ` + constant.ServerCubeResource + ` ` + constant.ServerDataSourceByName + ` const testAccCheckCubeServerConfigBootCdromNoImage = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" + name = "Basic Cube XS" cores = 1 - ram = 1024 - storage_size = 30 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { @@ -521,10 +526,10 @@ resource ` + constant.ServerCubeResource + ` ` + constant.ServerTestResource + ` const testAccCheckCubeServerResolveImageName = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" + name = "Basic Cube XS" cores = 1 - ram = 1024 - storage_size = 30 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { @@ -563,10 +568,10 @@ resource ` + constant.ServerCubeResource + ` ` + constant.ServerTestResource + ` const testAccCheckCubeServerWithSnapshot = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" + name = "Basic Cube XS" cores = 1 - ram = 1024 - storage_size = 30 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { @@ -621,10 +626,10 @@ resource ` + constant.ServerCubeResource + ` ` + constant.ServerTestResource + ` const testAccCheckCubeServerNoFirewall = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" + name = "Basic Cube XS" cores = 1 - ram = 1024 - storage_size = 30 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { @@ -664,10 +669,10 @@ resource ` + constant.ServerCubeResource + ` ` + constant.ServerTestResource + ` const testAccCheckCubeServerICMP = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" + name = "Basic Cube XS" cores = 1 - ram = 1024 - storage_size = 30 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { diff --git a/ionoscloud/resource_server.go b/ionoscloud/resource_server.go index 723dcba7b..0af48b889 100644 --- a/ionoscloud/resource_server.go +++ b/ionoscloud/resource_server.go @@ -45,6 +45,12 @@ func resourceServer() *schema.Resource { Required: true, ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotWhiteSpace), }, + "hostname": { + Type: schema.TypeString, + Optional: true, + Description: "The hostname of the resource. Allowed characters are a-z, 0-9 and - (minus). Hostname should not start with minus and should not be longer than 63 characters.", + ValidateDiagFunc: validation.ToDiagFunc(validation.All(validation.StringIsNotWhiteSpace, validation.StringLenBetween(1, 63))), + }, "cores": { Type: schema.TypeInt, Optional: true, // this should be required when the deprecated version will be removed @@ -861,6 +867,11 @@ func resourceServerUpdate(ctx context.Context, d *schema.ResourceData, meta inte nStr := n.(string) request.Name = &nStr } + if d.HasChange("hostname") { + _, n := d.GetChange("hostname") + nStr := n.(string) + request.Hostname = &nStr + } if d.HasChange("cores") { _, n := d.GetChange("cores") nInt := int32(n.(int)) @@ -1373,7 +1384,10 @@ func getServerData(d *schema.ResourceData) (*ionoscloud.Server, error) { server.Properties.CpuFamily = &vStr } } - + if v, ok := d.GetOk("hostname"); ok { + vStr := v.(string) + server.Properties.Hostname = &vStr + } if _, ok := d.GetOk("boot_cdrom"); ok { bootCdrom := d.Get("boot_cdrom").(string) if utils.IsValidUUID(bootCdrom) { @@ -1419,7 +1433,11 @@ func setResourceServerData(ctx context.Context, client *ionoscloud.APIClient, d return fmt.Errorf("error setting name %w", err) } } - + if server.Properties.Hostname != nil { + if err := d.Set("hostname", *server.Properties.Hostname); err != nil { + return fmt.Errorf("error setting hostname %w", err) + } + } if server.Properties.Cores != nil { if err := d.Set("cores", *server.Properties.Cores); err != nil { return fmt.Errorf("error setting cores %w", err) diff --git a/ionoscloud/resource_server_test.go b/ionoscloud/resource_server_test.go index 68e32f5e6..1a6941cf5 100644 --- a/ionoscloud/resource_server_test.go +++ b/ionoscloud/resource_server_test.go @@ -58,6 +58,7 @@ func TestAccServerBasic(t *testing.T) { Config: testAccCheckServerNoNic, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "name", constant.ServerTestResource), + resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "hostname", constant.ServerTestHostname), resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "cores", "1"), resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "ram", "1024"), resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "availability_zone", "ZONE_1"), @@ -68,6 +69,7 @@ func TestAccServerBasic(t *testing.T) { Config: testAccCheckServerNoNicUpdate, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "name", constant.ServerTestResource), + resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "hostname", constant.ServerTestHostname), resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "cores", "2"), resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "ram", "2048"), resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "availability_zone", "ZONE_1"), @@ -140,6 +142,7 @@ func TestAccServerBasic(t *testing.T) { Config: testAccDataSourceServerMatchId, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceById, "name", constant.ServerResource+"."+constant.ServerTestResource, "name"), + resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceById, "hostname", constant.ServerResource+"."+constant.ServerTestResource, "hostname"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceById, "cores", constant.ServerResource+"."+constant.ServerTestResource, "cores"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceById, "ram", constant.ServerResource+"."+constant.ServerTestResource, "ram"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceById, "availability_zone", constant.ServerResource+"."+constant.ServerTestResource, "availability_zone"), @@ -172,6 +175,7 @@ func TestAccServerBasic(t *testing.T) { Config: testAccDataSourceServerMatchName, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceByName, "name", constant.ServerResource+"."+constant.ServerTestResource, "name"), + resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceByName, "hostname", constant.ServerResource+"."+constant.ServerTestResource, "hostname"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceByName, "cores", constant.ServerResource+"."+constant.ServerTestResource, "cores"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceByName, "ram", constant.ServerResource+"."+constant.ServerTestResource, "ram"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceByName, "availability_zone", constant.ServerResource+"."+constant.ServerTestResource, "availability_zone"), @@ -208,6 +212,7 @@ func TestAccServerBasic(t *testing.T) { Config: testAccCheckServerConfigIpv6Enabled, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "nic.0.dhcpv6", "true"), + resource.TestCheckResourceAttr(constant.ServerResource+"."+constant.ServerTestResource, "hostname", "updated"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceById, "nics.0.dhcpv6", constant.ServerResource+"."+constant.ServerTestResource, "nic.0.dhcpv6"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceById, "nics.0.ipv6_cidr_block", constant.ServerResource+"."+constant.ServerTestResource, "nic.0.ipv6_cidr_block"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerResource+"."+constant.ServerDataSourceById, "nics.0.ipv6_ips.0", constant.ServerResource+"."+constant.ServerTestResource, "nic.0.ipv6_ips.0"), @@ -1599,10 +1604,10 @@ resource ` + constant.RandomPassword + ` "server_image_password" { const testAccCheckCubeServerAndServersDataSource = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" - cores = 1 - ram = 1024 - storage_size = 30 + name = "Basic Cube XS" + cores = 1 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + " " + constant.DatacenterTestResource + `{ diff --git a/ionoscloud/resource_vcpu_server.go b/ionoscloud/resource_vcpu_server.go index 559953ff7..d69fbee0c 100644 --- a/ionoscloud/resource_vcpu_server.go +++ b/ionoscloud/resource_vcpu_server.go @@ -27,6 +27,12 @@ func resourceVCPUServer() *schema.Resource { Required: true, ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotWhiteSpace), }, + "hostname": { + Type: schema.TypeString, + Optional: true, + Description: "The hostname of the resource. Allowed characters are a-z, 0-9 and - (minus). Hostname should not start with minus and should not be longer than 63 characters.", + ValidateDiagFunc: validation.ToDiagFunc(validation.All(validation.StringIsNotWhiteSpace, validation.StringLenBetween(1, 63))), + }, "cores": { Type: schema.TypeInt, Required: true, diff --git a/ionoscloud/resource_vcpu_server_test.go b/ionoscloud/resource_vcpu_server_test.go index 5a0b0a97d..16234f722 100644 --- a/ionoscloud/resource_vcpu_server_test.go +++ b/ionoscloud/resource_vcpu_server_test.go @@ -44,6 +44,7 @@ func TestAccServerVCPUBasic(t *testing.T) { Config: testAccCheckServerVCPUNoNic, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "name", constant.ServerTestResource), + resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "hostname", constant.ServerTestHostname), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "cores", "1"), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "ram", "1024"), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "availability_zone", "ZONE_1"), @@ -62,6 +63,7 @@ func TestAccServerVCPUBasic(t *testing.T) { Config: testAccCheckServerVCPUNoNicUpdate, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "name", constant.ServerTestResource), + resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "hostname", "updated"), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "cores", "2"), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "ram", "2048"), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "vm_state", constant.VMStateStop), @@ -109,6 +111,7 @@ func TestAccServerVCPUBasic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckServerVCPUExists(constant.ServerVCPUResource+"."+constant.ServerTestResource, &server), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "name", constant.ServerTestResource), + resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "hostname", constant.ServerTestHostname), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "cores", "1"), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "ram", "1024"), resource.TestCheckResourceAttr(constant.ServerVCPUResource+"."+constant.ServerTestResource, "availability_zone", "ZONE_1"), @@ -144,6 +147,7 @@ func TestAccServerVCPUBasic(t *testing.T) { Config: testAccDataSourceServerVCPUMatchId, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceById, "name", constant.ServerVCPUResource+"."+constant.ServerTestResource, "name"), + resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceById, "hostname", constant.ServerVCPUResource+"."+constant.ServerTestResource, "hostname"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceById, "cores", constant.ServerVCPUResource+"."+constant.ServerTestResource, "cores"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceById, "ram", constant.ServerVCPUResource+"."+constant.ServerTestResource, "ram"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceById, "availability_zone", constant.ServerVCPUResource+"."+constant.ServerTestResource, "availability_zone"), @@ -176,6 +180,7 @@ func TestAccServerVCPUBasic(t *testing.T) { Config: testAccDataSourceServerVCPUMatchName, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceByName, "name", constant.ServerVCPUResource+"."+constant.ServerTestResource, "name"), + resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceByName, "hostname", constant.ServerVCPUResource+"."+constant.ServerTestResource, "hostname"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceByName, "cores", constant.ServerVCPUResource+"."+constant.ServerTestResource, "cores"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceByName, "ram", constant.ServerVCPUResource+"."+constant.ServerTestResource, "ram"), resource.TestCheckResourceAttrPair(constant.DataSource+"."+constant.ServerVCPUResource+"."+constant.ServerDataSourceByName, "availability_zone", constant.ServerVCPUResource+"."+constant.ServerTestResource, "availability_zone"), diff --git a/ionoscloud/resource_volume.go b/ionoscloud/resource_volume.go index 5cd01afde..4822067d2 100644 --- a/ionoscloud/resource_volume.go +++ b/ionoscloud/resource_volume.go @@ -245,8 +245,8 @@ func resourceVolumeCreate(ctx context.Context, d *schema.ResourceData, meta inte diags := diag.FromErr(fmt.Errorf("it is mandatory to provide either public image that has cloud-init compatibility in conjunction with backup_unit_id property ")) return diags } else { - backupUnitId := backupUnitId.(string) - volume.Properties.BackupunitId = &backupUnitId + backupUnitID := backupUnitId.(string) + volume.Properties.BackupunitId = &backupUnitID } } else { diags := diag.FromErr(fmt.Errorf("the backup_unit_id that you specified is not a valid UUID")) diff --git a/ionoscloud/test_constants.go b/ionoscloud/test_constants.go index 7d3754690..d3be65f5b 100644 --- a/ionoscloud/test_constants.go +++ b/ionoscloud/test_constants.go @@ -288,6 +288,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.ServerTestResource + `" + hostname = "` + constant.ServerTestHostname + `" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id cores = 1 ram = 1024 @@ -425,6 +426,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.ServerTestResource + `" + hostname = "updated" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id cores = 1 ram = 1024 @@ -690,10 +692,10 @@ resource ` + constant.RandomPassword + ` "server_image_password_updated" { // Cube Server Constants const testAccCheckCubeServerConfigBasic = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" + name = "Basic Cube XS" cores = 1 - ram = 1024 - storage_size = 30 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { name = "server-test" @@ -712,6 +714,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { resource ` + constant.ServerCubeResource + ` ` + constant.ServerTestResource + ` { template_uuid = data.ionoscloud_template.` + constant.ServerTestResource + `.id name = "` + constant.ServerTestResource + `" + hostname = "` + constant.ServerTestHostname + `" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id availability_zone = "AUTO" image_name ="ubuntu:latest" @@ -745,10 +748,10 @@ resource ` + constant.ServerCubeResource + ` ` + constant.ServerTestResource + ` const testAccCheckCubeServerEnableIpv6 = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" - cores = 1 - ram = 1024 - storage_size = 30 + name = "Basic Cube XS" + cores = 1 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { name = "server-test" @@ -814,10 +817,10 @@ data ` + constant.ServerCubeResource + ` ` + constant.ServerDataSourceById + ` { ` const testAccCheckCubeServerUpdateIpv6 = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" - cores = 1 - ram = 1024 - storage_size = 30 + name = "Basic Cube XS" + cores = 1 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { name = "server-test" @@ -883,10 +886,10 @@ data ` + constant.ServerCubeResource + ` ` + constant.ServerDataSourceById + ` { ` const testAccCheckCubeServerSuspend = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" - cores = 1 - ram = 1024 - storage_size = 30 + name = "Basic Cube XS" + cores = 1 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { name = "server-test" @@ -945,10 +948,10 @@ data ` + constant.ServerCubeResource + ` ` + constant.ServerDataSourceById + ` { ` const testAccCheckCubeServerResume = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" - cores = 1 - ram = 1024 - storage_size = 30 + name = "Basic Cube XS" + cores = 1 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { name = "server-test" @@ -1008,10 +1011,10 @@ data ` + constant.ServerCubeResource + ` ` + constant.ServerDataSourceById + ` { const testAccCheckCubeServerUpdateWhenSuspended = ` data "ionoscloud_template" ` + constant.ServerTestResource + ` { - name = "CUBES XS" - cores = 1 - ram = 1024 - storage_size = 30 + name = "Basic Cube XS" + cores = 1 + ram = 2048 + storage_size = 60 } resource ` + constant.DatacenterResource + ` ` + constant.DatacenterTestResource + ` { name = "server-test" @@ -1130,6 +1133,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.ServerTestResource + `" + hostname = "` + constant.ServerTestHostname + `" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id cores = 1 ram = 1024 @@ -1165,6 +1169,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.ServerTestResource + `" + hostname = "` + constant.ServerTestHostname + `" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id cores = 2 ram = 2048 @@ -1409,6 +1414,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerVCPUResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.ServerTestResource + `" + hostname = "` + constant.ServerTestHostname + `" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id cores = 1 ram = 1024 @@ -1561,6 +1567,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerVCPUResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.ServerTestResource + `" + hostname = "` + constant.ServerTestHostname + `" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id cores = 1 ram = 1024 @@ -1593,6 +1600,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerVCPUResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.ServerTestResource + `" + hostname = "updated" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id cores = 2 ram = 2048 @@ -1627,6 +1635,7 @@ resource ` + constant.LanResource + ` ` + constant.LanTestResource + ` { } resource ` + constant.ServerVCPUResource + ` ` + constant.ServerTestResource + ` { name = "` + constant.ServerTestResource + `" + hostname = "` + constant.ServerTestHostname + `" datacenter_id = ` + constant.DatacenterResource + `.` + constant.DatacenterTestResource + `.id vm_state = "` + constant.VMStateStop + `" cores = 1 diff --git a/utils/constant/constants.go b/utils/constant/constants.go index afec380ee..6a1f6fa8a 100644 --- a/utils/constant/constants.go +++ b/utils/constant/constants.go @@ -187,6 +187,7 @@ const ( ServerCubeResource = "ionoscloud_cube_server" ServerVCPUResource = "ionoscloud_vcpu_server" ServerTestResource = "test_server" + ServerTestHostname = "myhostname" ServerDataSourceById = "test_server_id" ServerDataSourceByName = "test_server_name" )