From 600847a2ea936ec1bbf37c448edf475227f9b904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palet?= Date: Wed, 6 Nov 2024 14:21:17 +0000 Subject: [PATCH] Revert "Implement key pair resource (#578)" (#581) This reverts commit 153947fd7ba7cf56208bb15116352adcb5a8ce63. --- docs/data-sources/key_pair.md | 36 -- docs/data-sources/public_ip.md | 4 +- docs/resources/key_pair.md | 74 ---- docs/resources/server.md | 234 +++++----- .../stackit_key_pair/data-source.tf | 3 - go.mod | 1 - go.sum | 2 - .../internal/services/iaas/iaas_acc_test.go | 173 -------- .../internal/services/iaas/keypair/const.go | 25 -- .../services/iaas/keypair/datasource.go | 155 ------- .../services/iaas/keypair/resource.go | 411 ------------------ .../services/iaas/keypair/resource_test.go | 211 --------- .../services/iaas/publicip/datasource.go | 4 +- .../internal/services/iaas/server/const.go | 32 +- .../internal/services/iaas/server/resource.go | 2 +- stackit/provider.go | 3 - 16 files changed, 113 insertions(+), 1257 deletions(-) delete mode 100644 docs/data-sources/key_pair.md delete mode 100644 docs/resources/key_pair.md delete mode 100644 examples/data-sources/stackit_key_pair/data-source.tf delete mode 100644 stackit/internal/services/iaas/keypair/const.go delete mode 100644 stackit/internal/services/iaas/keypair/datasource.go delete mode 100644 stackit/internal/services/iaas/keypair/resource.go delete mode 100644 stackit/internal/services/iaas/keypair/resource_test.go diff --git a/docs/data-sources/key_pair.md b/docs/data-sources/key_pair.md deleted file mode 100644 index f370793b..00000000 --- a/docs/data-sources/key_pair.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "stackit_key_pair Data Source - stackit" -subcategory: "" -description: |- - Key pair resource schema. Must have a region specified in the provider configuration. - ~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our guide https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources for how to opt-in to use beta resources. ---- - -# stackit_key_pair (Data Source) - -Key pair resource schema. Must have a `region` specified in the provider configuration. - -~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our [guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources) for how to opt-in to use beta resources. - -## Example Usage - -```terraform -data "stackit_key_pair" "example" { - name = "example-key-pair-name" -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the SSH key pair. - -### Read-Only - -- `fingerprint` (String) The fingerprint of the public SSH key. -- `id` (String) Terraform's internal resource ID. It takes the value of the key pair "`name`". -- `labels` (Map of String) Labels are key-value string pairs which can be attached to a resource container. -- `public_key` (String) A string representation of the public SSH key. E.g., `ssh-rsa ` or `ssh-ed25519 `. diff --git a/docs/data-sources/public_ip.md b/docs/data-sources/public_ip.md index bd4a480f..fb4010b7 100644 --- a/docs/data-sources/public_ip.md +++ b/docs/data-sources/public_ip.md @@ -3,13 +3,13 @@ page_title: "stackit_public_ip Data Source - stackit" subcategory: "" description: |- - Public IP resource schema. Must have a region specified in the provider configuration. + Volume resource schema. Must have a region specified in the provider configuration. ~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our guide https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources for how to opt-in to use beta resources. --- # stackit_public_ip (Data Source) -Public IP resource schema. Must have a `region` specified in the provider configuration. +Volume resource schema. Must have a `region` specified in the provider configuration. ~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our [guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources) for how to opt-in to use beta resources. diff --git a/docs/resources/key_pair.md b/docs/resources/key_pair.md deleted file mode 100644 index 67bbf0ec..00000000 --- a/docs/resources/key_pair.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "stackit_key_pair Resource - stackit" -subcategory: "" -description: |- - Key pair resource schema. Must have a region specified in the provider configuration. Allows uploading an SSH public key to be used for server authentication. - Usage with server - ```terraform - resource "stackitkeypair" "keypair" { - name = "example-key-pair" - publickey = chomp(file("path/to/idrsa.pub")) - } - resource "stackitserver" "example-server" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - name = "example-server" - bootvolume = { - size = 64 - sourcetype = "image" - sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - availabilityzone = "eu01-1" - machinetype = "g1.1" - keypairname = "example-key-pair" - } - ~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our guide https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources for how to opt-in to use beta resources. ---- - -# stackit_key_pair (Resource) - -Key pair resource schema. Must have a `region` specified in the provider configuration. Allows uploading an SSH public key to be used for server authentication. - - - -### Usage with server -```terraform -resource "stackit_key_pair" "keypair" { - name = "example-key-pair" - public_key = chomp(file("path/to/id_rsa.pub")) -} - -resource "stackit_server" "example-server" { - project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - name = "example-server" - boot_volume = { - size = 64 - source_type = "image" - source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - availability_zone = "eu01-1" - machine_type = "g1.1" - keypair_name = "example-key-pair" -} - - -~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our [guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources) for how to opt-in to use beta resources. - - - - -## Schema - -### Required - -- `name` (String) The name of the SSH key pair. -- `public_key` (String) A string representation of the public SSH key. E.g., `ssh-rsa ` or `ssh-ed25519 `. - -### Optional - -- `labels` (Map of String) Labels are key-value string pairs which can be attached to a resource container. - -### Read-Only - -- `fingerprint` (String) The fingerprint of the public SSH key. -- `id` (String) Terraform's internal resource ID. It takes the value of the key pair "`name`". diff --git a/docs/resources/server.md b/docs/resources/server.md index 59b493c6..18ecd935 100644 --- a/docs/resources/server.md +++ b/docs/resources/server.md @@ -6,44 +6,26 @@ description: |- Server resource schema. Must have a region specified in the provider configuration. ~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our guide https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources for how to opt-in to use beta resources. Example Usage - With key pair - ```terraform - resource "stackitkeypair" "keypair" { - name = "example-key-pair" - publickey = chomp(file("path/to/idrsa.pub")) - } - resource "stackitserver" "user-data-from-file" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - bootvolume = { - size = 64 - sourcetype = "image" - sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - name = "example-server" - machinetype = "g1.1" - keypairname = stackitkeypair.keypair.name - userdata = file("${path.module}/cloud-init.yaml") - } - ``` Boot from volume - ```terraform - resource "stackitserver" "boot-from-volume" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + + resource "stackit_server" "boot-from-volume" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example-server" - bootvolume = { + boot_volume = { size = 64 - sourcetype = "image" - sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + source_type = "image" + source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } - availabilityzone = "eu01-1" - machinetype = "g1.1" - keypairname = "example-keypair" + availability_zone = "eu01-1" + machine_type = "g1.1" + keypair_name = "example-keypair" } - ``` + + Boot from existing volume - ```terraform - resource "stackitvolume" "example-volume" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + + resource "stackit_volume" "example-volume" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" size = 12 source = { type = "image" @@ -52,117 +34,129 @@ description: |- name = "example-volume" availability_zone = "eu01-1" } - resource "stackitserver" "boot-from-volume" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + + resource "stackit_server" "boot-from-volume" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example-server" - bootvolume = { - sourcetype = "volume" - sourceid = stackitvolume.example-volume.volumeid + boot_volume = { + source_type = "volume" + source_id = stackit_volume.example-volume.volume_id } - availabilityzone = "eu01-1" - machinetype = "g1.1" - keypairname = stackitkeypair.keypair.name + availability_zone = "eu01-1" + machine_type = "g1.1" + keypair_name = "example-keypair" } - ``` + + Network setup - ```terraform - resource "stackitserver" "server-with-network" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + + resource "stackit_server" "server-with-network" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example-server" - bootvolume = { + boot_volume = { size = 64 - sourcetype = "image" - sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + source_type = "image" + source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } - machinetype = "g1.1" - keypairname = stackitkey_pair.keypair.name + machine_type = "g1.1" + keypair_name = "example-keypair" } - resource "stackitnetwork" "network" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + + resource "stackit_network" "network" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example-network" nameservers = ["192.0.2.0", "198.51.100.0", "203.0.113.0"] - ipv4prefixlength = 24 + ipv4_prefix_length = 24 } - resource "stackitsecuritygroup" "sec-group" { + + resource "stackit_security_group" "sec-group" { project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example-security-group" stateful = true } - resource "stackitsecuritygrouprule" "rule" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - securitygroupid = stackitsecuritygroup.sec-group.securitygroupid + + resource "stackit_security_group_rule" "rule" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + security_group_id = stackit_security_group.sec-group.security_group_id direction = "ingress" ether_type = "IPv4" } - resource "stackitnetworkinterface" "nic" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - networkid = stackitnetwork.network.networkid - securitygroupids = [stackitsecuritygroup.sec-group.securitygroupid] + + resource "stackit_network_interface" "nic" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + network_id = stackit_network.network.network_id + security_group_ids = [stackit_security_group.sec-group.security_group_id] } - resource "stackitpublicip" "public-ip" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - networkinterfaceid = stackitnetworkinterface.nic.networkinterface_id + + resource "stackit_public_ip" "public-ip" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + network_interface_id = stackit_network_interface.nic.network_interface_id } - resource "stackitservernetworkinterfaceattach" "nic-attachment" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - serverid = stackitserver.server-with-network.serverid - networkinterfaceid = stackitnetworkinterface.nic.networkinterfaceid + + resource "stackit_server_network_interface_attach" "nic-attachment" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + server_id = stackit_server.server-with-network.server_id + network_interface_id = stackit_network_interface.nic.network_interface_id } - ``` + + Server with attached volume - ```terraform - resource "stackitvolume" "example-volume" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + + resource "stackit_volume" "example-volume" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" size = 12 - performanceclass = "storagepremiumperf6" + performance_class = "storage_premium_perf6" name = "example-volume" - availabilityzone = "eu01-1" + availability_zone = "eu01-1" } - resource "stackitserver" "server-with-volume" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + + resource "stackit_server" "server-with-volume" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example-server" - bootvolume = { + boot_volume = { size = 64 - sourcetype = "image" - sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + source_type = "image" + source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } - availabilityzone = "eu01-1" - machinetype = "g1.1" - keypairname = stackitkeypair.keypair.name + availability_zone = "eu01-1" + machine_type = "g1.1" + keypair_name = "example-keypair" } - resource "stackitservervolumeattach" "attachvolume" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - serverid = stackitserver.server-with-volume.serverid - volumeid = stackitvolume.example-volume.volume_id + + resource "stackit_server_volume_attach" "attach_volume" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + server_id = stackit_server.server-with-volume.server_id + volume_id = stackit_volume.example-volume.volume_id } - ``` + + Server with user data (cloud-init) - ```terraform - resource "stackitserver" "user-data" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - bootvolume = { + + resource "stackit_server" "user-data" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + boot_volume = { size = 64 - sourcetype = "image" - sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + source_type = "image" + source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } name = "example-server" - machinetype = "g1.1" - keypairname = stackitkeypair.keypair.name - userdata = "#!/bin/bash\n/bin/su" + machine_type = "g1.1" + keypair_name = "example-keypair" + user_data = "#!/bin/bash\n/bin/su" } - resource "stackitserver" "user-data-from-file" { - projectid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - bootvolume = { + + resource "stackit_server" "user-data-from-file" { + project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + boot_volume = { size = 64 - sourcetype = "image" - sourceid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + source_type = "image" + source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } name = "example-server" - machinetype = "g1.1" - keypairname = stackitkeypair.keypair.name - userdata = file("${path.module}/cloud-init.yaml") + machine_type = "g1.1" + keypair_name = "example-keypair" + user_data = file("${path.module}/cloud-init.yaml") } - ``` --- # stackit_server (Resource) @@ -173,28 +167,6 @@ Server resource schema. Must have a region specified in the provider configurati ## Example Usage -### With key pair -```terraform -resource "stackit_key_pair" "keypair" { - name = "example-key-pair" - public_key = chomp(file("path/to/id_rsa.pub")) -} - -resource "stackit_server" "user-data-from-file" { - project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - boot_volume = { - size = 64 - source_type = "image" - source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - name = "example-server" - machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name - user_data = file("${path.module}/cloud-init.yaml") -} - -``` - ### Boot from volume ```terraform resource "stackit_server" "boot-from-volume" { @@ -234,7 +206,7 @@ resource "stackit_server" "boot-from-volume" { } availability_zone = "eu01-1" machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" } ``` @@ -250,7 +222,7 @@ resource "stackit_server" "server-with-network" { source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" } resource "stackit_network" "network" { @@ -312,7 +284,7 @@ resource "stackit_server" "server-with-volume" { } availability_zone = "eu01-1" machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" } resource "stackit_server_volume_attach" "attach_volume" { @@ -334,7 +306,7 @@ resource "stackit_server" "user-data" { } name = "example-server" machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" user_data = "#!/bin/bash\n/bin/su" } @@ -347,7 +319,7 @@ resource "stackit_server" "user-data-from-file" { } name = "example-server" machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" user_data = file("${path.module}/cloud-init.yaml") } diff --git a/examples/data-sources/stackit_key_pair/data-source.tf b/examples/data-sources/stackit_key_pair/data-source.tf deleted file mode 100644 index 6fbd302b..00000000 --- a/examples/data-sources/stackit_key_pair/data-source.tf +++ /dev/null @@ -1,3 +0,0 @@ -data "stackit_key_pair" "example" { - name = "example-key-pair-name" -} diff --git a/go.mod b/go.mod index 187f07f7..ff14cb71 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,6 @@ require ( github.com/stackitcloud/stackit-sdk-go/services/argus v0.11.0 github.com/stackitcloud/stackit-sdk-go/services/dns v0.11.0 github.com/stackitcloud/stackit-sdk-go/services/iaas v0.15.0 - github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.12-alpha github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v0.17.0 github.com/stackitcloud/stackit-sdk-go/services/logme v0.20.0 github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.20.0 diff --git a/go.sum b/go.sum index d3b6a2f9..99055645 100644 --- a/go.sum +++ b/go.sum @@ -157,8 +157,6 @@ github.com/stackitcloud/stackit-sdk-go/services/dns v0.11.0 h1:+OZ82DwFy4JIJThad github.com/stackitcloud/stackit-sdk-go/services/dns v0.11.0/go.mod h1:mv8U7kuclXo+0VpDHtBCkve/3i9h1yT+RAId/MUi+C8= github.com/stackitcloud/stackit-sdk-go/services/iaas v0.15.0 h1:bPNv+PuSykBcKCYVXHiYOcqNP+KLCA7XMFSY4V6J6ug= github.com/stackitcloud/stackit-sdk-go/services/iaas v0.15.0/go.mod h1:YfuN+eXuqr846xeRyW2Vf1JM2jU0ikeQa76dDI66RsM= -github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.12-alpha h1:jwpif4t2gthmKmCXsQ84rmtDdcZkw4QQTFiCd7nTW8M= -github.com/stackitcloud/stackit-sdk-go/services/iaasalpha v0.1.12-alpha/go.mod h1:nW/6vvumUHA7o1/JOOqsrEOBNrRHombEKB1U4jmg2wU= github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v0.17.0 h1:06CGP64CEk3Zg6i9kZCMRdmCzLLiyMWQqGK1teBr9Oc= github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v0.17.0/go.mod h1:JL94zc8K0ebWs+DBGXR28vNCF0EFV54ZLUtrlXOvWgA= github.com/stackitcloud/stackit-sdk-go/services/logme v0.20.0 h1:V0UGP7JEa4Q8SsZFUJsKgLGaoPruLn2KVKnqQtaoWCU= diff --git a/stackit/internal/services/iaas/iaas_acc_test.go b/stackit/internal/services/iaas/iaas_acc_test.go index 2cad184b..f95549a6 100644 --- a/stackit/internal/services/iaas/iaas_acc_test.go +++ b/stackit/internal/services/iaas/iaas_acc_test.go @@ -12,7 +12,6 @@ import ( "github.com/stackitcloud/stackit-sdk-go/core/config" "github.com/stackitcloud/stackit-sdk-go/core/utils" "github.com/stackitcloud/stackit-sdk-go/services/iaas" - "github.com/stackitcloud/stackit-sdk-go/services/iaasalpha" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/testutil" ) @@ -97,14 +96,6 @@ var publicIpResource = map[string]string{ "network_interface_id": testutil.IaaSNetworkInterfaceId, } -// Key pair resource data -var keyPairResource = map[string]string{ - "name": "key-pair-name", - "public_key": `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIDsPd27M449akqCtdFg2+AmRVJz6eWio0oMP9dVg7XZ`, - "label1": "value1", - "label1-updated": "value1-updated", -} - func networkResourceConfig(name, nameservers string) string { return fmt.Sprintf(` resource "stackit_network" "network" { @@ -332,13 +323,6 @@ func testAccPublicIpConfig(publicIpResourceConfig string) string { ) } -func testAccKeyPairConfig(keyPairResourceConfig string) string { - return fmt.Sprintf("%s\n\n%s", - testutil.IaaSProviderConfig(), - keyPairResourceConfig, - ) -} - func TestAccNetworkArea(t *testing.T) { resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories, @@ -1129,117 +1113,6 @@ func TestAccPublicIp(t *testing.T) { }) } -func TestAccKeyPair(t *testing.T) { - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories, - CheckDestroy: testAccCheckIaaSKeyPairDestroy, - Steps: []resource.TestStep{ - - // Creation - { - Config: testAccKeyPairConfig( - fmt.Sprintf(` - resource "stackit_key_pair" "key_pair" { - name = "%s" - public_key = "%s" - labels = { - "label1" = "%s" - } - } - `, - keyPairResource["name"], - keyPairResource["public_key"], - keyPairResource["label1"], - ), - ), - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("stackit_key_pair.key_pair", "name", keyPairResource["name"]), - resource.TestCheckResourceAttr("stackit_key_pair.key_pair", "labels.label1", keyPairResource["label1"]), - resource.TestCheckResourceAttr("stackit_key_pair.key_pair", "public_key", keyPairResource["public_key"]), - resource.TestCheckResourceAttrSet("stackit_key_pair.key_pair", "fingerprint"), - ), - }, - // Data source - { - Config: fmt.Sprintf(` - %s - - data "stackit_key_pair" "key_pair" { - name = stackit_key_pair.key_pair.name - } - `, - testAccKeyPairConfig( - fmt.Sprintf(` - resource "stackit_key_pair" "key_pair" { - name = "%s" - public_key = "%s" - labels = { - "label1" = "%s" - } - } - `, - keyPairResource["name"], - keyPairResource["public_key"], - keyPairResource["label1"], - ), - ), - ), - Check: resource.ComposeAggregateTestCheckFunc( - // Instance - resource.TestCheckResourceAttr("data.stackit_key_pair.key_pair", "name", keyPairResource["name"]), - resource.TestCheckResourceAttr("data.stackit_key_pair.key_pair", "public_key", keyPairResource["public_key"]), - resource.TestCheckResourceAttr("stackit_key_pair.key_pair", "labels.label1", keyPairResource["label1"]), - resource.TestCheckResourceAttrPair( - "stackit_key_pair.key_pair", "fingerprint", - "data.stackit_key_pair.key_pair", "fingerprint", - ), - ), - }, - // Import - { - ResourceName: "stackit_key_pair.key_pair", - ImportStateIdFunc: func(s *terraform.State) (string, error) { - r, ok := s.RootModule().Resources["stackit_key_pair.key_pair"] - if !ok { - return "", fmt.Errorf("couldn't find resource stackit_key_pair.key_pair") - } - keyPairName, ok := r.Primary.Attributes["name"] - if !ok { - return "", fmt.Errorf("couldn't find attribute name") - } - return keyPairName, nil - }, - ImportState: true, - ImportStateVerify: true, - }, - // Update - { - Config: testAccKeyPairConfig( - fmt.Sprintf(` - resource "stackit_key_pair" "key_pair" { - name = "%s" - public_key = "%s" - labels = { - "label1" = "%s" - } - } - `, - keyPairResource["name"], - keyPairResource["public_key"], - keyPairResource["label1-updated"], - ), - ), - Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("stackit_key_pair.key_pair", "name", keyPairResource["name"]), - resource.TestCheckResourceAttr("stackit_key_pair.key_pair", "labels.label1", keyPairResource["label1-updated"]), - resource.TestCheckResourceAttrSet("stackit_key_pair.key_pair", "fingerprint"), - ), - }, - // Deletion is done by the framework implicitly - }, - }) -} - func testAccCheckNetworkAreaDestroy(s *terraform.State) error { ctx := context.Background() var client *iaas.APIClient @@ -1515,49 +1388,3 @@ func testAccCheckIaaSPublicIpDestroy(s *terraform.State) error { } return nil } - -func testAccCheckIaaSKeyPairDestroy(s *terraform.State) error { - ctx := context.Background() - var client *iaasalpha.APIClient - var err error - if testutil.IaaSCustomEndpoint == "" { - client, err = iaasalpha.NewAPIClient( - config.WithRegion("eu01"), - ) - } else { - client, err = iaasalpha.NewAPIClient( - config.WithEndpoint(testutil.IaaSCustomEndpoint), - ) - } - if err != nil { - return fmt.Errorf("creating client: %w", err) - } - - keyPairsToDestroy := []string{} - for _, rs := range s.RootModule().Resources { - if rs.Type != "stackit_key_pair" { - continue - } - // Key pair terraform ID: "[name]" - keyPairsToDestroy = append(keyPairsToDestroy, rs.Primary.ID) - } - - keyPairsResp, err := client.ListKeyPairsExecute(ctx) - if err != nil { - return fmt.Errorf("getting key pairs: %w", err) - } - - keyPairs := *keyPairsResp.Items - for i := range keyPairs { - if keyPairs[i].Name == nil { - continue - } - if utils.Contains(keyPairsToDestroy, *keyPairs[i].Name) { - err := client.DeleteKeyPairExecute(ctx, *keyPairs[i].Name) - if err != nil { - return fmt.Errorf("destroying key pair %s during CheckDestroy: %w", *keyPairs[i].Name, err) - } - } - } - return nil -} diff --git a/stackit/internal/services/iaas/keypair/const.go b/stackit/internal/services/iaas/keypair/const.go deleted file mode 100644 index fe8305bf..00000000 --- a/stackit/internal/services/iaas/keypair/const.go +++ /dev/null @@ -1,25 +0,0 @@ -package keypair - -const exampleUsageWithServer = ` - -### Usage with server` + "\n" + - - "```terraform" + ` -resource "stackit_key_pair" "keypair" { - name = "example-key-pair" - public_key = chomp(file("path/to/id_rsa.pub")) -} - -resource "stackit_server" "example-server" { - project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - name = "example-server" - boot_volume = { - size = 64 - source_type = "image" - source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - availability_zone = "eu01-1" - machine_type = "g1.1" - keypair_name = "example-key-pair" -} -` diff --git a/stackit/internal/services/iaas/keypair/datasource.go b/stackit/internal/services/iaas/keypair/datasource.go deleted file mode 100644 index 2846632a..00000000 --- a/stackit/internal/services/iaas/keypair/datasource.go +++ /dev/null @@ -1,155 +0,0 @@ -package keypair - -import ( - "context" - "fmt" - "net/http" - - "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/stackitcloud/stackit-sdk-go/core/config" - "github.com/stackitcloud/stackit-sdk-go/core/oapierror" - "github.com/stackitcloud/stackit-sdk-go/services/iaasalpha" - "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" - "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/features" -) - -// keyPairDataSourceBetaCheckDone is used to prevent multiple checks for beta resources. -// This is a workaround for the lack of a global state in the provider and -// needs to exist because the Configure method is called twice. -var keyPairDataSourceBetaCheckDone bool - -// Ensure the implementation satisfies the expected interfaces. -var ( - _ datasource.DataSource = &keyPairDataSource{} -) - -// NewVolumeDataSource is a helper function to simplify the provider implementation. -func NewKeyPairDataSource() datasource.DataSource { - return &keyPairDataSource{} -} - -// keyPairDataSource is the data source implementation. -type keyPairDataSource struct { - client *iaasalpha.APIClient -} - -// Metadata returns the data source type name. -func (d *keyPairDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_key_pair" -} - -func (d *keyPairDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { - // Prevent panic if the provider has not been configured. - if req.ProviderData == nil { - return - } - - var apiClient *iaasalpha.APIClient - var err error - - providerData, ok := req.ProviderData.(core.ProviderData) - if !ok { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Expected configure type stackit.ProviderData, got %T", req.ProviderData)) - return - } - - if !keyPairDataSourceBetaCheckDone { - features.CheckBetaResourcesEnabled(ctx, &providerData, &resp.Diagnostics, "stackit_key_pair", "data source") - if resp.Diagnostics.HasError() { - return - } - keyPairDataSourceBetaCheckDone = true - } - - if providerData.IaaSCustomEndpoint != "" { - apiClient, err = iaasalpha.NewAPIClient( - config.WithCustomAuth(providerData.RoundTripper), - config.WithEndpoint(providerData.IaaSCustomEndpoint), - ) - } else { - apiClient, err = iaasalpha.NewAPIClient( - config.WithCustomAuth(providerData.RoundTripper), - config.WithRegion(providerData.Region), - ) - } - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Configuring client: %v. This is an error related to the provider configuration, not to the data source configuration", err)) - return - } - - d.client = apiClient - tflog.Info(ctx, "iaasalpha client configured") -} - -// Schema defines the schema for the resource. -func (r *keyPairDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { - description := "Key pair resource schema. Must have a `region` specified in the provider configuration." - - resp.Schema = schema.Schema{ - MarkdownDescription: features.AddBetaDescription(description), - Description: description, - Attributes: map[string]schema.Attribute{ - "id": schema.StringAttribute{ - Description: "Terraform's internal resource ID. It takes the value of the key pair \"`name`\".", - Computed: true, - }, - "name": schema.StringAttribute{ - Description: "The name of the SSH key pair.", - Required: true, - }, - "public_key": schema.StringAttribute{ - Description: "A string representation of the public SSH key. E.g., `ssh-rsa ` or `ssh-ed25519 `.", - Computed: true, - }, - "fingerprint": schema.StringAttribute{ - Description: "The fingerprint of the public SSH key.", - Computed: true, - }, - "labels": schema.MapAttribute{ - Description: "Labels are key-value string pairs which can be attached to a resource container.", - ElementType: types.StringType, - Computed: true, - }, - }, - } -} - -// Read refreshes the Terraform state with the latest data. -func (r *keyPairDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform - var model Model - diags := req.Config.Get(ctx, &model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - name := model.Name.ValueString() - ctx = tflog.SetField(ctx, "name", name) - - keypairResp, err := r.client.GetKeyPair(ctx, name).Execute() - if err != nil { - oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped - if ok && oapiErr.StatusCode == http.StatusNotFound { - resp.State.RemoveResource(ctx) - return - } - core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading key pair", fmt.Sprintf("Calling API: %v", err)) - return - } - - // Map response body to schema - err = mapFields(ctx, keypairResp, &model) - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading key pair", fmt.Sprintf("Processing API payload: %v", err)) - return - } - // Set refreshed state - diags = resp.State.Set(ctx, model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - tflog.Info(ctx, "Key pair read") -} diff --git a/stackit/internal/services/iaas/keypair/resource.go b/stackit/internal/services/iaas/keypair/resource.go deleted file mode 100644 index 226f263f..00000000 --- a/stackit/internal/services/iaas/keypair/resource.go +++ /dev/null @@ -1,411 +0,0 @@ -package keypair - -import ( - "context" - "fmt" - "net/http" - "strings" - - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/stackitcloud/stackit-sdk-go/core/config" - "github.com/stackitcloud/stackit-sdk-go/core/oapierror" - "github.com/stackitcloud/stackit-sdk-go/services/iaasalpha" - "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion" - "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core" - "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/features" -) - -// resourceBetaCheckDone is used to prevent multiple checks for beta resources. -// This is a workaround for the lack of a global state in the provider and -// needs to exist because the Configure method is called twice. -var resourceBetaCheckDone bool - -// Ensure the implementation satisfies the expected interfaces. -var ( - _ resource.Resource = &keyPairResource{} - _ resource.ResourceWithConfigure = &keyPairResource{} - _ resource.ResourceWithImportState = &keyPairResource{} -) - -type Model struct { - Id types.String `tfsdk:"id"` // needed by TF - Name types.String `tfsdk:"name"` - PublicKey types.String `tfsdk:"public_key"` - Fingerprint types.String `tfsdk:"fingerprint"` - Labels types.Map `tfsdk:"labels"` -} - -// NewKeyPairResource is a helper function to simplify the provider implementation. -func NewKeyPairResource() resource.Resource { - return &keyPairResource{} -} - -// keyPairResource is the resource implementation. -type keyPairResource struct { - client *iaasalpha.APIClient -} - -// Metadata returns the resource type name. -func (r *keyPairResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_key_pair" -} - -// Configure adds the provider configured client to the resource. -func (r *keyPairResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - // Prevent panic if the provider has not been configured. - if req.ProviderData == nil { - return - } - - providerData, ok := req.ProviderData.(core.ProviderData) - if !ok { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Expected configure type stackit.ProviderData, got %T", req.ProviderData)) - return - } - - if !resourceBetaCheckDone { - features.CheckBetaResourcesEnabled(ctx, &providerData, &resp.Diagnostics, "stackit_key_pair", "resource") - if resp.Diagnostics.HasError() { - return - } - resourceBetaCheckDone = true - } - - var apiClient *iaasalpha.APIClient - var err error - if providerData.IaaSCustomEndpoint != "" { - ctx = tflog.SetField(ctx, "iaasalpha_custom_endpoint", providerData.IaaSCustomEndpoint) - apiClient, err = iaasalpha.NewAPIClient( - config.WithCustomAuth(providerData.RoundTripper), - config.WithEndpoint(providerData.IaaSCustomEndpoint), - ) - } else { - apiClient, err = iaasalpha.NewAPIClient( - config.WithCustomAuth(providerData.RoundTripper), - config.WithRegion(providerData.Region), - ) - } - - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration", err)) - return - } - - r.client = apiClient - tflog.Info(ctx, "iaasalpha client configured") -} - -// Schema defines the schema for the resource. -func (r *keyPairResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { - description := "Key pair resource schema. Must have a `region` specified in the provider configuration. Allows uploading an SSH public key to be used for server authentication." - - resp.Schema = schema.Schema{ - MarkdownDescription: features.AddBetaDescription(description + "\n\n" + exampleUsageWithServer), - Description: description, - Attributes: map[string]schema.Attribute{ - "id": schema.StringAttribute{ - Description: "Terraform's internal resource ID. It takes the value of the key pair \"`name`\".", - Computed: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - }, - "name": schema.StringAttribute{ - Description: "The name of the SSH key pair.", - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - }, - "public_key": schema.StringAttribute{ - Description: "A string representation of the public SSH key. E.g., `ssh-rsa ` or `ssh-ed25519 `.", - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), - }, - }, - "fingerprint": schema.StringAttribute{ - Description: "The fingerprint of the public SSH key.", - Computed: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - }, - "labels": schema.MapAttribute{ - Description: "Labels are key-value string pairs which can be attached to a resource container.", - ElementType: types.StringType, - Optional: true, - }, - }, - } -} - -// ModifyPlan will be called in the Plan phase. -// It will check if the plan contains a change that requires replacement. If yes, it will show a warning to the user. -func (r *keyPairResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { // nolint:gocritic // function signature required by Terraform - // If the state is empty we are creating a new resource - // If the plan is empty we are deleting the resource - // In both cases we don't need to check for replacement - if req.Plan.Raw.IsNull() || req.State.Raw.IsNull() { - return - } - - var planModel Model - diags := req.Plan.Get(ctx, &planModel) - resp.Diagnostics.Append(diags...) - - var stateModel Model - diags = req.State.Get(ctx, &stateModel) - resp.Diagnostics.Append(diags...) - - if planModel.PublicKey.ValueString() != stateModel.PublicKey.ValueString() { - core.LogAndAddWarning(ctx, &resp.Diagnostics, "Key pair public key change", "Changing the public key will trigger a replacement of the key pair resource. The new key pair will not be valid to access servers on which the old key was used, as the key is only registered during server creation.") - } -} - -// Create creates the resource and sets the initial Terraform state. -func (r *keyPairResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { // nolint:gocritic // function signature required by Terraform - // Retrieve values from plan - var model Model - diags := req.Plan.Get(ctx, &model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - name := model.Name.ValueString() - ctx = tflog.SetField(ctx, "name", name) - - // Generate API request body from model - payload, err := toCreatePayload(ctx, &model) - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating key pair", fmt.Sprintf("Creating API payload: %v", err)) - return - } - - // Create new key pair - - keyPair, err := r.client.CreateKeyPair(ctx).CreateKeyPairPayload(*payload).Execute() - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating key pair", fmt.Sprintf("Calling API: %v", err)) - return - } - - // Map response body to schema - err = mapFields(ctx, keyPair, &model) - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating key pair", fmt.Sprintf("Processing API payload: %v", err)) - return - } - // Set state to fully populated data - diags = resp.State.Set(ctx, model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - tflog.Info(ctx, "Key pair created") -} - -// Read refreshes the Terraform state with the latest data. -func (r *keyPairResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { // nolint:gocritic // function signature required by Terraform - var model Model - diags := req.State.Get(ctx, &model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - name := model.Name.ValueString() - ctx = tflog.SetField(ctx, "name", name) - - keyPairResp, err := r.client.GetKeyPair(ctx, name).Execute() - if err != nil { - oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped - if ok && oapiErr.StatusCode == http.StatusNotFound { - resp.State.RemoveResource(ctx) - return - } - core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading key pair", fmt.Sprintf("Calling API: %v", err)) - return - } - - // Map response body to schema - err = mapFields(ctx, keyPairResp, &model) - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading key pair", fmt.Sprintf("Processing API payload: %v", err)) - return - } - // Set refreshed state - diags = resp.State.Set(ctx, model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - tflog.Info(ctx, "Key pair read") -} - -// Update updates the resource and sets the updated Terraform state on success. -func (r *keyPairResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { // nolint:gocritic // function signature required by Terraform - // Retrieve values from plan - var model Model - diags := req.Plan.Get(ctx, &model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - name := model.Name.ValueString() - ctx = tflog.SetField(ctx, "name", name) - - // Retrieve values from state - var stateModel Model - diags = req.State.Get(ctx, &stateModel) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - // Generate API request body from model - payload, err := toUpdatePayload(ctx, &model, stateModel.Labels) - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating key pair", fmt.Sprintf("Creating API payload: %v", err)) - return - } - // Update existing key pair - updatedKeyPair, err := r.client.UpdateKeyPair(ctx, name).UpdateKeyPairPayload(*payload).Execute() - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating key pair", fmt.Sprintf("Calling API: %v", err)) - return - } - - err = mapFields(ctx, updatedKeyPair, &model) - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating key pair", fmt.Sprintf("Processing API payload: %v", err)) - return - } - diags = resp.State.Set(ctx, model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - tflog.Info(ctx, "key pair updated") -} - -// Delete deletes the resource and removes the Terraform state on success. -func (r *keyPairResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { // nolint:gocritic // function signature required by Terraform - // Retrieve values from state - var model Model - diags := req.State.Get(ctx, &model) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - name := model.Name.ValueString() - ctx = tflog.SetField(ctx, "name", name) - - // Delete existing key pair - err := r.client.DeleteKeyPair(ctx, name).Execute() - if err != nil { - core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting key pair", fmt.Sprintf("Calling API: %v", err)) - return - } - - tflog.Info(ctx, "Key pair deleted") -} - -// ImportState imports a resource into the Terraform state on success. -// The expected format of the resource import identifier is: project_id,key_pair_id -func (r *keyPairResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - idParts := strings.Split(req.ID, core.Separator) - - if len(idParts) != 1 || idParts[0] == "" { - core.LogAndAddError(ctx, &resp.Diagnostics, - "Error importing key pair", - fmt.Sprintf("Expected import identifier with format: [name] Got: %q", req.ID), - ) - return - } - - name := idParts[0] - ctx = tflog.SetField(ctx, "name", name) - - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("name"), name)...) - tflog.Info(ctx, "Key pair state imported") -} - -func mapFields(ctx context.Context, keyPairResp *iaasalpha.Keypair, model *Model) error { - if keyPairResp == nil { - return fmt.Errorf("response input is nil") - } - if model == nil { - return fmt.Errorf("model input is nil") - } - - var name string - if model.Name.ValueString() != "" { - name = model.Name.ValueString() - } else if keyPairResp.Name != nil { - name = *keyPairResp.Name - } else { - return fmt.Errorf("key pair name not present") - } - - model.Id = types.StringValue(name) - model.PublicKey = types.StringPointerValue(keyPairResp.PublicKey) - model.Fingerprint = types.StringPointerValue(keyPairResp.Fingerprint) - - labels, diags := types.MapValueFrom(ctx, types.StringType, map[string]interface{}{}) - if diags.HasError() { - return fmt.Errorf("converting labels to StringValue map: %w", core.DiagsToError(diags)) - } - if keyPairResp.Labels != nil && len(*keyPairResp.Labels) != 0 { - var diags diag.Diagnostics - labels, diags = types.MapValueFrom(ctx, types.StringType, *keyPairResp.Labels) - if diags.HasError() { - return fmt.Errorf("converting labels to StringValue map: %w", core.DiagsToError(diags)) - } - } else if model.Labels.IsNull() { - labels = types.MapNull(types.StringType) - } - model.Labels = labels - - return nil -} - -func toCreatePayload(ctx context.Context, model *Model) (*iaasalpha.CreateKeyPairPayload, error) { - if model == nil { - return nil, fmt.Errorf("nil model") - } - - labels, err := conversion.ToStringInterfaceMap(ctx, model.Labels) - if err != nil { - return nil, fmt.Errorf("converting to Go map: %w", err) - } - - return &iaasalpha.CreateKeyPairPayload{ - Name: conversion.StringValueToPointer(model.Name), - PublicKey: conversion.StringValueToPointer(model.PublicKey), - Labels: &labels, - }, nil -} - -func toUpdatePayload(ctx context.Context, model *Model, currentLabels types.Map) (*iaasalpha.UpdateKeyPairPayload, error) { - if model == nil { - return nil, fmt.Errorf("nil model") - } - - labels, err := conversion.ToJSONMapPartialUpdatePayload(ctx, currentLabels, model.Labels) - if err != nil { - return nil, fmt.Errorf("converting to Go map: %w", err) - } - - return &iaasalpha.UpdateKeyPairPayload{ - Labels: &labels, - }, nil -} diff --git a/stackit/internal/services/iaas/keypair/resource_test.go b/stackit/internal/services/iaas/keypair/resource_test.go deleted file mode 100644 index f318d9ae..00000000 --- a/stackit/internal/services/iaas/keypair/resource_test.go +++ /dev/null @@ -1,211 +0,0 @@ -package keypair - -import ( - "context" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stackitcloud/stackit-sdk-go/core/utils" - "github.com/stackitcloud/stackit-sdk-go/services/iaasalpha" -) - -func TestMapFields(t *testing.T) { - tests := []struct { - description string - state Model - input *iaasalpha.Keypair - expected Model - isValid bool - }{ - { - "default_values", - Model{ - Name: types.StringValue("name"), - }, - &iaasalpha.Keypair{ - Name: utils.Ptr("name"), - }, - Model{ - Id: types.StringValue("name"), - Name: types.StringValue("name"), - PublicKey: types.StringNull(), - Fingerprint: types.StringNull(), - Labels: types.MapNull(types.StringType), - }, - true, - }, - { - "simple_values", - Model{ - Name: types.StringValue("name"), - }, - &iaasalpha.Keypair{ - Name: utils.Ptr("name"), - PublicKey: utils.Ptr("public_key"), - Fingerprint: utils.Ptr("fingerprint"), - Labels: &map[string]interface{}{ - "key": "value", - }, - }, - Model{ - Id: types.StringValue("name"), - Name: types.StringValue("name"), - PublicKey: types.StringValue("public_key"), - Fingerprint: types.StringValue("fingerprint"), - Labels: types.MapValueMust(types.StringType, map[string]attr.Value{ - "key": types.StringValue("value"), - }), - }, - true, - }, - { - "empty_labels", - Model{ - Name: types.StringValue("name"), - }, - &iaasalpha.Keypair{ - Name: utils.Ptr("name"), - PublicKey: utils.Ptr("public_key"), - Fingerprint: utils.Ptr("fingerprint"), - Labels: &map[string]interface{}{}, - }, - Model{ - Id: types.StringValue("name"), - Name: types.StringValue("name"), - PublicKey: types.StringValue("public_key"), - Fingerprint: types.StringValue("fingerprint"), - Labels: types.MapNull(types.StringType), - }, - true, - }, - { - "response_nil_fail", - Model{}, - nil, - Model{}, - false, - }, - { - "no_resource_id", - Model{}, - &iaasalpha.Keypair{ - PublicKey: utils.Ptr("public_key"), - Fingerprint: utils.Ptr("fingerprint"), - Labels: &map[string]interface{}{}, - }, - Model{}, - false, - }, - } - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - err := mapFields(context.Background(), tt.input, &tt.state) - if !tt.isValid && err == nil { - t.Fatalf("Should have failed") - } - if tt.isValid && err != nil { - t.Fatalf("Should not have failed: %v", err) - } - if tt.isValid { - diff := cmp.Diff(tt.state, tt.expected) - if diff != "" { - t.Fatalf("Data does not match: %s", diff) - } - } - }) - } -} - -func TestToCreatePayload(t *testing.T) { - tests := []struct { - description string - input *Model - expected *iaasalpha.CreateKeyPairPayload - isValid bool - }{ - { - "default_ok", - &Model{ - Name: types.StringValue("name"), - PublicKey: types.StringValue("public_key"), - Labels: types.MapValueMust(types.StringType, map[string]attr.Value{ - "key1": types.StringValue("value1"), - "key2": types.StringValue("value2"), - }), - }, - &iaasalpha.CreateKeyPairPayload{ - Name: utils.Ptr("name"), - PublicKey: utils.Ptr("public_key"), - Labels: &map[string]interface{}{ - "key1": "value1", - "key2": "value2", - }, - }, - true, - }, - } - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - output, err := toCreatePayload(context.Background(), tt.input) - if !tt.isValid && err == nil { - t.Fatalf("Should have failed") - } - if tt.isValid && err != nil { - t.Fatalf("Should not have failed: %v", err) - } - if tt.isValid { - diff := cmp.Diff(output, tt.expected, cmp.AllowUnexported(iaasalpha.NullableString{})) - if diff != "" { - t.Fatalf("Data does not match: %s", diff) - } - } - }) - } -} - -func TestToUpdatePayload(t *testing.T) { - tests := []struct { - description string - input *Model - expected *iaasalpha.UpdateKeyPairPayload - isValid bool - }{ - { - "default_ok", - &Model{ - Name: types.StringValue("name"), - PublicKey: types.StringValue("public_key"), - Labels: types.MapValueMust(types.StringType, map[string]attr.Value{ - "key1": types.StringValue("value1"), - "key2": types.StringValue("value2"), - }), - }, - &iaasalpha.UpdateKeyPairPayload{ - Labels: &map[string]interface{}{ - "key1": "value1", - "key2": "value2", - }, - }, - true, - }, - } - for _, tt := range tests { - t.Run(tt.description, func(t *testing.T) { - output, err := toUpdatePayload(context.Background(), tt.input, types.MapNull(types.StringType)) - if !tt.isValid && err == nil { - t.Fatalf("Should have failed") - } - if tt.isValid && err != nil { - t.Fatalf("Should not have failed: %v", err) - } - if tt.isValid { - diff := cmp.Diff(output, tt.expected, cmp.AllowUnexported(iaasalpha.NullableString{})) - if diff != "" { - t.Fatalf("Data does not match: %s", diff) - } - } - }) - } -} diff --git a/stackit/internal/services/iaas/publicip/datasource.go b/stackit/internal/services/iaas/publicip/datasource.go index bd0d46e4..f530b5a1 100644 --- a/stackit/internal/services/iaas/publicip/datasource.go +++ b/stackit/internal/services/iaas/publicip/datasource.go @@ -89,8 +89,8 @@ func (d *publicIpDataSource) Configure(ctx context.Context, req datasource.Confi // Schema defines the schema for the resource. func (r *publicIpDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = schema.Schema{ - MarkdownDescription: features.AddBetaDescription("Public IP resource schema. Must have a `region` specified in the provider configuration."), - Description: "Public IP resource schema. Must have a `region` specified in the provider configuration.", + MarkdownDescription: features.AddBetaDescription("Volume resource schema. Must have a `region` specified in the provider configuration."), + Description: "Volume resource schema. Must have a `region` specified in the provider configuration.", Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ Description: "Terraform's internal datasource ID. It is structured as \"`project_id`,`public_ip_id`\".", diff --git a/stackit/internal/services/iaas/server/const.go b/stackit/internal/services/iaas/server/const.go index 0ed54368..6db84be9 100644 --- a/stackit/internal/services/iaas/server/const.go +++ b/stackit/internal/services/iaas/server/const.go @@ -5,28 +5,6 @@ Server resource schema. Must have a region specified in the provider configurati ~> This resource is in beta and may be subject to breaking changes in the future. Use with caution. See our [guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources) for how to opt-in to use beta resources. ## Example Usage` + "\n" + ` -### With key pair` + "\n" + - - "```terraform" + ` -resource "stackit_key_pair" "keypair" { - name = "example-key-pair" - public_key = chomp(file("path/to/id_rsa.pub")) -} - -resource "stackit_server" "user-data-from-file" { - project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - boot_volume = { - size = 64 - source_type = "image" - source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - } - name = "example-server" - machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name - user_data = file("${path.module}/cloud-init.yaml") -} -` + "\n```" + ` - ### Boot from volume` + "\n" + "```terraform" + ` @@ -67,7 +45,7 @@ resource "stackit_server" "boot-from-volume" { } availability_zone = "eu01-1" machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" } ` + "\n```" + ` @@ -83,7 +61,7 @@ resource "stackit_server" "server-with-network" { source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" } resource "stackit_network" "network" { @@ -145,7 +123,7 @@ resource "stackit_server" "server-with-volume" { } availability_zone = "eu01-1" machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" } resource "stackit_server_volume_attach" "attach_volume" { @@ -167,7 +145,7 @@ resource "stackit_server" "user-data" { } name = "example-server" machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" user_data = "#!/bin/bash\n/bin/su" } @@ -180,7 +158,7 @@ resource "stackit_server" "user-data-from-file" { } name = "example-server" machine_type = "g1.1" - keypair_name = stackit_key_pair.keypair.name + keypair_name = "example-keypair" user_data = file("${path.module}/cloud-init.yaml") } ` + "\n```" diff --git a/stackit/internal/services/iaas/server/resource.go b/stackit/internal/services/iaas/server/resource.go index e4c071a7..99a8a897 100644 --- a/stackit/internal/services/iaas/server/resource.go +++ b/stackit/internal/services/iaas/server/resource.go @@ -563,7 +563,7 @@ func mapFields(ctx context.Context, serverResp *iaas.Server, model *Model) error } else if serverResp.Id != nil { serverId = *serverResp.Id } else { - return fmt.Errorf("server id not present") + return fmt.Errorf("Server id not present") } idParts := []string{ diff --git a/stackit/provider.go b/stackit/provider.go index f3fd0286..620e604e 100644 --- a/stackit/provider.go +++ b/stackit/provider.go @@ -14,7 +14,6 @@ import ( argusScrapeConfig "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/argus/scrapeconfig" dnsRecordSet "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/dns/recordset" dnsZone "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/dns/zone" - iaasKeyPair "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/keypair" iaasNetwork "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/network" iaasNetworkArea "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/networkarea" iaasNetworkAreaRoute "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/networkarearoute" @@ -413,7 +412,6 @@ func (p *Provider) DataSources(_ context.Context) []func() datasource.DataSource iaasNetworkInterface.NewNetworkInterfaceDataSource, iaasVolume.NewVolumeDataSource, iaasPublicIp.NewPublicIpDataSource, - iaasKeyPair.NewKeyPairDataSource, iaasServer.NewServerDataSource, iaasSecurityGroup.NewSecurityGroupDataSource, iaasSecurityGroupRule.NewSecurityGroupRuleDataSource, @@ -464,7 +462,6 @@ func (p *Provider) Resources(_ context.Context) []func() resource.Resource { iaasNetworkInterface.NewNetworkInterfaceResource, iaasVolume.NewVolumeResource, iaasPublicIp.NewPublicIpResource, - iaasKeyPair.NewKeyPairResource, iaasVolumeAttach.NewVolumeAttachResource, iaasNetworkInterfaceAttach.NewNetworkInterfaceAttachResource, iaasServiceAccountAttach.NewServiceAccountAttachResource,