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{}) {