From 570c987b0e1a979d5e1cc2f81d3bfcdc3bb90c78 Mon Sep 17 00:00:00 2001
From: alexk53 <98004722+alexk53@users.noreply.github.com>
Date: Wed, 11 Sep 2024 11:48:08 +0200
Subject: [PATCH] gcore_instancev2 remove deprecated params (#129)
---
docs/resources/instancev2.md | 27 +--
docs/resources/lbmember.md | 1 -
.../gcore_instancev2/one-interface-windows.tf | 1 -
.../gcore_lbmember/instance-member.tf | 1 -
gcore/resource_gcore_instancev2.go | 176 ++++--------------
5 files changed, 50 insertions(+), 156 deletions(-)
diff --git a/docs/resources/instancev2.md b/docs/resources/instancev2.md
index cf06aef..e98e9a9 100644
--- a/docs/resources/instancev2.md
+++ b/docs/resources/instancev2.md
@@ -151,7 +151,6 @@ resource "gcore_instancev2" "instance" {
password = "my-s3cR3tP@ssw0rd"
volume {
- source = "existing-volume"
volume_id = gcore_volume.boot_volume_windows.id
boot_index = 0
}
@@ -383,7 +382,9 @@ resource "gcore_instancev2" "instance" {
### Required
- `flavor_id` (String) Flavor ID
-- `interface` (Block Set, Min: 1) List of interfaces for the instance. (see [below for nested schema](#nestedblock--interface))
+- `interface` (Block Set, Min: 1) List of interfaces for the instance. You can detach the interface from the instance by removing the
+interface from the instance resource and attach the interface by adding the interface resource
+inside an instance resource. (see [below for nested schema](#nestedblock--interface))
### Optional
@@ -392,12 +393,10 @@ resource "gcore_instancev2" "instance" {
- `configuration` (Block List) Parameters for the application template from the marketplace (see [below for nested schema](#nestedblock--configuration))
- `keypair_name` (String) Name of the keypair to use for the instance
- `last_updated` (String)
-- `metadata` (Block List, Deprecated) (see [below for nested schema](#nestedblock--metadata))
- `metadata_map` (Map of String) Create one or more metadata items for the instance
- `name` (String) Name of the instance.
- `name_template` (String) Instance name template. You can use forms 'ip_octets', 'two_ip_octets', 'one_ip_octet'
-- `name_templates` (List of String, Deprecated) List of instance names which will be changed by template. You can use forms 'ip_octets', 'two_ip_octets', 'one_ip_octet'
-- `password` (String) For Linux instances, 'username' and 'password' are used to create a new user.
+- `password` (String, Sensitive) For Linux instances, 'username' and 'password' are used to create a new user.
When only 'password' is provided, it is set as the password for the default user of the image. 'user_data' is ignored
when 'password' is specified. For Windows instances, 'username' cannot be specified. Use the 'password' field to set
the password for the 'Admin' user on Windows. Use the 'user_data' field to provide a script to create new users
@@ -409,18 +408,19 @@ on Windows. The password of the Admin user cannot be updated via 'user_data'
- `server_group` (String) ID of the server group to use for the instance
- `user_data` (String) String in base64 format. For Linux instances, 'user_data' is ignored when 'password' field is provided.
For Windows instances, Admin user password is set by 'password' field and cannot be updated via 'user_data'
-- `userdata` (String, Deprecated) **Deprecated**
- `username` (String) For Linux instances, 'username' and 'password' are used to create a new user. For Windows
instances, 'username' cannot be specified. Use 'password' field to set the password for the 'Admin' user on Windows.
- `vm_state` (String) Current vm state, use stopped to stop vm and active to start
-- `volume` (Block Set) List of volumes for the instance (see [below for nested schema](#nestedblock--volume))
+- `volume` (Block Set) List of volumes for the instance. You can detach the volume from the instance by removing the
+volume from the instance resource. You cannot detach the boot volume. You can attach a data volume
+by adding the volume resource inside an instance resource. (see [below for nested schema](#nestedblock--volume))
### Read-Only
- `addresses` (List of Object) List of instance addresses (see [below for nested schema](#nestedatt--addresses))
- `flavor` (Map of String) Flavor details, RAM, vCPU, etc.
- `id` (String) The ID of this resource.
-- `security_group` (List of Object) Firewalls list (see [below for nested schema](#nestedatt--security_group))
+- `security_group` (List of Object) Firewalls list, they will be attached globally on all instance's interfaces (see [below for nested schema](#nestedatt--security_group))
- `status` (String) Status of the instance
@@ -437,7 +437,7 @@ Optional:
- `network_id` (String) required if type is 'subnet' or 'any_subnet'
- `order` (Number) Order of attaching interface
- `port_id` (String) required if type is 'reserved_fixed_ip'
-- `security_groups` (List of String) list of security group IDs
+- `security_groups` (List of String) list of security group IDs, they will be attached to exact interface
- `subnet_id` (String) required if type is 'subnet'
- `type` (String) Available value is 'subnet', 'any_subnet', 'external', 'reserved_fixed_ip'
@@ -451,15 +451,6 @@ Required:
- `value` (String)
-
-### Nested Schema for `metadata`
-
-Required:
-
-- `key` (String)
-- `value` (String)
-
-
### Nested Schema for `volume`
diff --git a/docs/resources/lbmember.md b/docs/resources/lbmember.md
index 531d51e..f0b3149 100644
--- a/docs/resources/lbmember.md
+++ b/docs/resources/lbmember.md
@@ -182,7 +182,6 @@ resource "gcore_instancev2" "instance_member" {
flavor_id = "g1-standard-1-2"
volume {
- source = "existing-volume"
volume_id = gcore_volume.instance_member_volume.id
boot_index = 0
}
diff --git a/examples/resources/gcore_instancev2/one-interface-windows.tf b/examples/resources/gcore_instancev2/one-interface-windows.tf
index adce127..30d415c 100644
--- a/examples/resources/gcore_instancev2/one-interface-windows.tf
+++ b/examples/resources/gcore_instancev2/one-interface-windows.tf
@@ -19,7 +19,6 @@ resource "gcore_instancev2" "instance" {
password = "my-s3cR3tP@ssw0rd"
volume {
- source = "existing-volume"
volume_id = gcore_volume.boot_volume_windows.id
boot_index = 0
}
diff --git a/examples/resources/gcore_lbmember/instance-member.tf b/examples/resources/gcore_lbmember/instance-member.tf
index 0b8be33..2955e95 100644
--- a/examples/resources/gcore_lbmember/instance-member.tf
+++ b/examples/resources/gcore_lbmember/instance-member.tf
@@ -51,7 +51,6 @@ resource "gcore_instancev2" "instance_member" {
flavor_id = "g1-standard-1-2"
volume {
- source = "existing-volume"
volume_id = gcore_volume.instance_member_volume.id
boot_index = 0
}
diff --git a/gcore/resource_gcore_instancev2.go b/gcore/resource_gcore_instancev2.go
index ed97d28..ef5af04 100644
--- a/gcore/resource_gcore_instancev2.go
+++ b/gcore/resource_gcore_instancev2.go
@@ -94,25 +94,19 @@ your applications.`,
Description: "Name of the instance.",
Computed: true,
},
- "name_templates": &schema.Schema{
- Type: schema.TypeList,
- Optional: true,
- Description: "List of instance names which will be changed by template. You can use forms 'ip_octets', 'two_ip_octets', 'one_ip_octet'",
- Deprecated: "Use name_template instead",
- ConflictsWith: []string{"name_template"},
- Elem: &schema.Schema{Type: schema.TypeString},
- },
"name_template": &schema.Schema{
- Type: schema.TypeString,
- Optional: true,
- Description: "Instance name template. You can use forms 'ip_octets', 'two_ip_octets', 'one_ip_octet'",
- ConflictsWith: []string{"name_templates"},
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Instance name template. You can use forms 'ip_octets', 'two_ip_octets', 'one_ip_octet'",
},
"volume": &schema.Schema{
- Type: schema.TypeSet,
- Optional: true,
- Description: "List of volumes for the instance",
- Set: volumeUniqueID,
+ Type: schema.TypeSet,
+ Optional: true,
+ Description: `
+List of volumes for the instance. You can detach the volume from the instance by removing the
+volume from the instance resource. You cannot detach the boot volume. You can attach a data volume
+by adding the volume resource inside an instance resource.`,
+ Set: volumeUniqueID,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
@@ -159,10 +153,13 @@ your applications.`,
},
},
"interface": &schema.Schema{
- Type: schema.TypeSet,
- Set: instanceInterfaceUniqueID,
- Required: true,
- Description: "List of interfaces for the instance.",
+ Type: schema.TypeSet,
+ Set: instanceInterfaceUniqueID,
+ Required: true,
+ Description: `
+List of interfaces for the instance. You can detach the interface from the instance by removing the
+interface from the instance resource and attach the interface by adding the interface resource
+inside an instance resource.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
@@ -206,7 +203,7 @@ your applications.`,
"security_groups": {
Type: schema.TypeList,
Optional: true,
- Description: "list of security group IDs",
+ Description: "list of security group IDs, they will be attached to exact interface",
Elem: &schema.Schema{Type: schema.TypeString},
},
"ip_address": {
@@ -230,7 +227,7 @@ your applications.`,
"security_group": &schema.Schema{
Type: schema.TypeList,
Computed: true,
- Description: "Firewalls list",
+ Description: "Firewalls list, they will be attached globally on all instance's interfaces",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
@@ -247,8 +244,9 @@ your applications.`,
},
},
"password": &schema.Schema{
- Type: schema.TypeString,
- Optional: true,
+ Type: schema.TypeString,
+ Optional: true,
+ Sensitive: true,
Description: `
For Linux instances, 'username' and 'password' are used to create a new user.
When only 'password' is provided, it is set as the password for the default user of the image. 'user_data' is ignored
@@ -263,29 +261,10 @@ on Windows. The password of the Admin user cannot be updated via 'user_data'`,
For Linux instances, 'username' and 'password' are used to create a new user. For Windows
instances, 'username' cannot be specified. Use 'password' field to set the password for the 'Admin' user on Windows.`,
},
- "metadata": &schema.Schema{
- Type: schema.TypeList,
- Optional: true,
- Deprecated: "Use metadata_map instead",
- ConflictsWith: []string{"metadata_map"},
- Elem: &schema.Resource{
- Schema: map[string]*schema.Schema{
- "key": {
- Type: schema.TypeString,
- Required: true,
- },
- "value": {
- Type: schema.TypeString,
- Required: true,
- },
- },
- },
- },
"metadata_map": &schema.Schema{
- Type: schema.TypeMap,
- Optional: true,
- Description: "Create one or more metadata items for the instance",
- ConflictsWith: []string{"metadata"},
+ Type: schema.TypeMap,
+ Optional: true,
+ Description: "Create one or more metadata items for the instance",
Elem: &schema.Schema{
Type: schema.TypeString,
},
@@ -307,21 +286,14 @@ instances, 'username' cannot be specified. Use 'password' field to set the passw
},
},
},
- "userdata": &schema.Schema{
- Type: schema.TypeString,
- Optional: true,
- Description: "**Deprecated**",
- Deprecated: "Use user_data instead",
- ConflictsWith: []string{"user_data"},
- },
"user_data": &schema.Schema{
Type: schema.TypeString,
Optional: true,
+ ForceNew: true,
Description: `
String in base64 format. For Linux instances, 'user_data' is ignored when 'password' field is provided.
For Windows instances, Admin user password is set by 'password' field and cannot be updated via 'user_data'
`,
- ConflictsWith: []string{"userdata"},
},
"allow_app_ports": &schema.Schema{
Type: schema.TypeBool,
@@ -405,9 +377,7 @@ func resourceInstanceV2Create(ctx context.Context, d *schema.ResourceData, m int
createOpts.Keypair = d.Get("keypair_name").(string)
createOpts.ServerGroupID = d.Get("server_group").(string)
- if userData, ok := d.GetOk("userdata"); ok {
- createOpts.UserData = userData.(string)
- } else if userData, ok := d.GetOk("user_data"); ok {
+ if userData, ok := d.GetOk("user_data"); ok {
createOpts.UserData = userData.(string)
}
@@ -416,16 +386,7 @@ func resourceInstanceV2Create(ctx context.Context, d *schema.ResourceData, m int
createOpts.Names = []string{name}
}
- if nameTemplatesRaw, ok := d.GetOk("name_templates"); ok {
- nameTemplates := nameTemplatesRaw.([]interface{})
- if len(nameTemplates) > 0 {
- NameTemp := make([]string, len(nameTemplates))
- for i, nametemp := range nameTemplates {
- NameTemp[i] = nametemp.(string)
- }
- createOpts.NameTemplates = NameTemp
- }
- } else if nameTemplate, ok := d.GetOk("name_template"); ok {
+ if nameTemplate, ok := d.GetOk("name_template"); ok {
createOpts.NameTemplates = []string{nameTemplate.(string)}
}
@@ -451,15 +412,7 @@ func resourceInstanceV2Create(ctx context.Context, d *schema.ResourceData, m int
createOpts.Interfaces = ifaces
}
- if metadata, ok := d.GetOk("metadata"); ok {
- if len(metadata.([]interface{})) > 0 {
- md, err := extractKeyValue(metadata.([]interface{}))
- if err != nil {
- return diag.FromErr(err)
- }
- createOpts.Metadata = &md
- }
- } else if metadataRaw, ok := d.GetOk("metadata_map"); ok {
+ if metadataRaw, ok := d.GetOk("metadata_map"); ok {
md := extractMetadataMap(metadataRaw.(map[string]interface{}))
createOpts.Metadata = &md
}
@@ -649,34 +602,17 @@ func resourceInstanceV2Read(ctx context.Context, d *schema.ResourceData, m inter
return diag.FromErr(err)
}
- if metadataRaw, ok := d.GetOk("metadata"); ok {
- metadata := metadataRaw.([]interface{})
- sliced := make([]map[string]string, len(metadata))
- for i, data := range metadata {
- d := data.(map[string]interface{})
- mdata := make(map[string]string, 2)
- md, err := instances.MetadataGet(client, instanceID, d["key"].(string)).Extract()
- if err != nil {
- return diag.Errorf("cannot get metadata with key: %s. Error: %s", instanceID, err)
- }
- mdata["key"] = md.Key
- mdata["value"] = md.Value
- sliced[i] = mdata
- }
- d.Set("metadata", sliced)
- } else {
- metadata := d.Get("metadata_map").(map[string]interface{})
- newMetadata := make(map[string]interface{}, len(metadata))
- for k := range metadata {
- md, err := instances.MetadataGet(client, instanceID, k).Extract()
- if err != nil {
- return diag.Errorf("cannot get metadata with key: %s. Error: %s", instanceID, err)
- }
- newMetadata[k] = md.Value
- }
- if err := d.Set("metadata_map", newMetadata); err != nil {
- return diag.FromErr(err)
+ metadata := d.Get("metadata_map").(map[string]interface{})
+ newMetadata := make(map[string]interface{}, len(metadata))
+ for k := range metadata {
+ md, err := instances.MetadataGet(client, instanceID, k).Extract()
+ if err != nil {
+ return diag.Errorf("cannot get metadata with key: %s. Error: %s", instanceID, err)
}
+ newMetadata[k] = md.Value
+ }
+ if err := d.Set("metadata_map", newMetadata); err != nil {
+ return diag.FromErr(err)
}
addresses := []map[string][]map[string]string{}
@@ -717,9 +653,8 @@ func resourceInstanceV2Update(ctx context.Context, d *schema.ResourceData, m int
}
if d.HasChange("name") {
- nameTemplates := d.Get("name_templates").([]interface{})
nameTemplate := d.Get("name_template").(string)
- if len(nameTemplate) == 0 && len(nameTemplates) == 0 {
+ if len(nameTemplate) == 0 {
opts := instances.RenameInstanceOpts{
Name: d.Get("name").(string),
}
@@ -751,36 +686,7 @@ func resourceInstanceV2Update(ctx context.Context, d *schema.ResourceData, m int
}
}
- if d.HasChange("metadata") {
- omd, nmd := d.GetChange("metadata")
- if len(omd.([]interface{})) > 0 {
- for _, data := range omd.([]interface{}) {
- d := data.(map[string]interface{})
- k := d["key"].(string)
- err := instances.MetadataDelete(client, instanceID, k).Err
- if err != nil {
- return diag.Errorf("cannot delete metadata key: %s. Error: %s", k, err)
- }
- }
- }
- if len(nmd.([]interface{})) > 0 {
- var MetaData []instances.MetadataOpts
- for _, data := range nmd.([]interface{}) {
- d := data.(map[string]interface{})
- var md instances.MetadataOpts
- md.Key = d["key"].(string)
- md.Value = d["value"].(string)
- MetaData = append(MetaData, md)
- }
- createOpts := instances.MetadataSetOpts{
- Metadata: MetaData,
- }
- err := instances.MetadataCreate(client, instanceID, createOpts).Err
- if err != nil {
- return diag.Errorf("cannot create metadata. Error: %s", err)
- }
- }
- } else if d.HasChange("metadata_map") {
+ if d.HasChange("metadata_map") {
omd, nmd := d.GetChange("metadata_map")
if len(omd.(map[string]interface{})) > 0 {
for k := range omd.(map[string]interface{}) {