From 97b16d20308c637a864855e11bd756fc6d8eaa89 Mon Sep 17 00:00:00 2001 From: Thijs van der Gugten Date: Mon, 10 Oct 2022 19:14:32 +0200 Subject: [PATCH 01/10] Add tests for importing templates --- opennebula/resource_opennebula_template.go | 40 ++++++++++++++++ .../resource_opennebula_template_test.go | 48 +++++++++++++++++-- ...esource_opennebula_virtual_machine_test.go | 2 +- ...resource_opennebula_virtual_router_test.go | 2 +- 4 files changed, 86 insertions(+), 6 deletions(-) diff --git a/opennebula/resource_opennebula_template.go b/opennebula/resource_opennebula_template.go index 2471deeea..17b54a3f9 100644 --- a/opennebula/resource_opennebula_template.go +++ b/opennebula/resource_opennebula_template.go @@ -424,9 +424,49 @@ func resourceOpennebulaTemplateReadCustom(ctx context.Context, d *schema.Resourc d.Set("gid", tpl.GID) d.Set("uname", tpl.UName) d.Set("gname", tpl.GName) + d.Set("group", tpl.GName) d.Set("reg_time", tpl.RegTime) + d.Set("description", "") + d.Set("sched_requirements", "") d.Set("permissions", permissionsUnixString(*tpl.Permissions)) + getTags := make(map[string]interface{}, 0) + for k, v := range pairsToMap(tpl.Template.Template) { + if k != "MEMORY" && k != "CPU" && k != "VCPU" && k != "VROUTER" && k != "DESCRIPTION" && k != "SCHED_REQUIREMENTS" { + getTags[strings.ToLower(k)] = v + } + } + d.Set("tags", getTags) + + for _, value := range tpl.Template.Elements { + if pair, ok := value.(*dyn.Pair); ok { + switch pair.XMLName.Local { + case "DESCRIPTION", "SCHED_REQUIREMENTS": + d.Set(strings.ToLower(pair.XMLName.Local), pair.Value) + } + } + if vector, ok := value.(*dyn.Vector); ok { + getOS := make(map[string]interface{}, 0) + switch vector.XMLName.Local { + case "OS", "FEATURES", "GRAPHICS", "CPU_MODEL": + for _, pair := range vector.Pairs { + getOS[strings.ToLower(pair.XMLName.Local)] = pair.Value + } + d.Set(strings.Replace(strings.ToLower(vector.XMLName.Local), "_", "", -1), append(make([]interface{}, 0), getOS)) + case "CONTEXT": + for _, pair := range vector.Pairs { + switch pair.XMLName.Local { + case "SET_HOSTNAME", "NETWORK": + getOS[pair.XMLName.Local] = pair.Value + default: + getOS[strings.ToLower(pair.XMLName.Local)] = pair.Value + } + } + d.Set(strings.ToLower(vector.XMLName.Local), getOS) + } + } + } + err = flattenTemplateDisks(d, &tpl.Template) if err != nil { diags = append(diags, diag.Diagnostic{ diff --git a/opennebula/resource_opennebula_template_test.go b/opennebula/resource_opennebula_template_test.go index 5f0284c95..6a3cbc585 100644 --- a/opennebula/resource_opennebula_template_test.go +++ b/opennebula/resource_opennebula_template_test.go @@ -25,6 +25,8 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "permissions", "660"), resource.TestCheckResourceAttr("opennebula_template.template", "group", "oneadmin"), resource.TestCheckResourceAttr("opennebula_template.template", "cpu", "0.5"), + resource.TestCheckResourceAttr("opennebula_template.template", "vcpu", "1"), + resource.TestCheckResourceAttr("opennebula_template.template", "memory", "512"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.0.keymap", "en-us"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.0.listen", "0.0.0.0"), @@ -32,6 +34,9 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "os.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "os.0.arch", "x86_64"), resource.TestCheckResourceAttr("opennebula_template.template", "os.0.boot", ""), + resource.TestCheckResourceAttr("opennebula_template.template", "context.%", "2"), + resource.TestCheckResourceAttr("opennebula_template.template", "context.dns_hostname", "yes"), + resource.TestCheckResourceAttr("opennebula_template.template", "context.NETWORK", "YES"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.%", "2"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.env", "prod"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.customer", "test"), @@ -55,6 +60,11 @@ func TestAccTemplate(t *testing.T) { }), ), }, + { + ResourceName: "opennebula_template.template", + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccTemplateCPUModel, Check: resource.ComposeTestCheckFunc( @@ -62,6 +72,8 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "permissions", "660"), resource.TestCheckResourceAttr("opennebula_template.template", "group", "oneadmin"), resource.TestCheckResourceAttr("opennebula_template.template", "cpu", "0.5"), + resource.TestCheckResourceAttr("opennebula_template.template", "vcpu", "1"), + resource.TestCheckResourceAttr("opennebula_template.template", "memory", "512"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.0.keymap", "en-us"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.0.listen", "0.0.0.0"), @@ -69,6 +81,9 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "os.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "os.0.arch", "x86_64"), resource.TestCheckResourceAttr("opennebula_template.template", "os.0.boot", ""), + resource.TestCheckResourceAttr("opennebula_template.template", "context.%", "2"), + resource.TestCheckResourceAttr("opennebula_template.template", "context.dns_hostname", "yes"), + resource.TestCheckResourceAttr("opennebula_template.template", "context.NETWORK", "YES"), resource.TestCheckResourceAttr("opennebula_template.template", "cpumodel.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "cpumodel.0.model", "host-passthrough"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.%", "2"), @@ -88,6 +103,11 @@ func TestAccTemplate(t *testing.T) { }), ), }, + { + ResourceName: "opennebula_template.template", + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccTemplateConfigUpdate, Check: resource.ComposeTestCheckFunc( @@ -95,6 +115,8 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "permissions", "642"), resource.TestCheckResourceAttr("opennebula_template.template", "group", "oneadmin"), resource.TestCheckResourceAttr("opennebula_template.template", "cpu", "1"), + resource.TestCheckResourceAttr("opennebula_template.template", "vcpu", "1"), + resource.TestCheckResourceAttr("opennebula_template.template", "memory", "768"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.0.keymap", "en-us"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.0.listen", "0.0.0.0"), @@ -102,6 +124,9 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "os.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "os.0.arch", "x86_64"), resource.TestCheckResourceAttr("opennebula_template.template", "os.0.boot", ""), + resource.TestCheckResourceAttr("opennebula_template.template", "context.%", "2"), + resource.TestCheckResourceAttr("opennebula_template.template", "context.dns_hostname", "yes"), + resource.TestCheckResourceAttr("opennebula_template.template", "context.NETWORK", "YES"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.%", "3"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.env", "dev"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.customer", "test"), @@ -124,6 +149,11 @@ func TestAccTemplate(t *testing.T) { }), ), }, + { + ResourceName: "opennebula_template.template", + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccTemplateConfigDelete, Check: resource.ComposeTestCheckFunc( @@ -131,6 +161,8 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "permissions", "642"), resource.TestCheckResourceAttr("opennebula_template.template", "group", "oneadmin"), resource.TestCheckResourceAttr("opennebula_template.template", "cpu", "1"), + resource.TestCheckResourceAttr("opennebula_template.template", "vcpu", "1"), + resource.TestCheckResourceAttr("opennebula_template.template", "memory", "768"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.0.keymap", "en-us"), resource.TestCheckResourceAttr("opennebula_template.template", "graphics.0.listen", "0.0.0.0"), @@ -138,6 +170,9 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "os.#", "1"), resource.TestCheckResourceAttr("opennebula_template.template", "os.0.arch", "x86_64"), resource.TestCheckResourceAttr("opennebula_template.template", "os.0.boot", ""), + resource.TestCheckResourceAttr("opennebula_template.template", "context.%", "2"), + resource.TestCheckResourceAttr("opennebula_template.template", "context.dns_hostname", "yes"), + resource.TestCheckResourceAttr("opennebula_template.template", "context.NETWORK", "YES"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.%", "2"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.env", "dev"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.customer", "test"), @@ -154,6 +189,11 @@ func TestAccTemplate(t *testing.T) { }), ), }, + { + ResourceName: "opennebula_template.template", + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -233,7 +273,7 @@ resource "opennebula_template" "template" { context = { dns_hostname = "yes" - network = "YES" + NETWORK = "YES" } graphics { @@ -273,7 +313,7 @@ resource "opennebula_template" "template" { context = { dns_hostname = "yes" - network = "YES" + NETWORK = "YES" } graphics { @@ -319,7 +359,7 @@ resource "opennebula_template" "template" { context = { dns_hostname = "yes" - network = "YES" + NETWORK = "YES" } graphics { @@ -356,7 +396,7 @@ resource "opennebula_template" "template" { context = { dns_hostname = "yes" - network = "YES" + NETWORK = "YES" } graphics { diff --git a/opennebula/resource_opennebula_virtual_machine_test.go b/opennebula/resource_opennebula_virtual_machine_test.go index 9a3cf5fa4..a2d3f79b5 100644 --- a/opennebula/resource_opennebula_virtual_machine_test.go +++ b/opennebula/resource_opennebula_virtual_machine_test.go @@ -2028,7 +2028,7 @@ resource "opennebula_template" "template" { context = { dns_hostname = "yes" - network = "YES" + NETWORK = "YES" } graphics { diff --git a/opennebula/resource_opennebula_virtual_router_test.go b/opennebula/resource_opennebula_virtual_router_test.go index 356afc7ef..d9fb02f96 100644 --- a/opennebula/resource_opennebula_virtual_router_test.go +++ b/opennebula/resource_opennebula_virtual_router_test.go @@ -231,7 +231,7 @@ resource "opennebula_virtual_router_instance_template" "test" { context = { dns_hostname = "yes" - network = "YES" + NETWORK = "YES" } graphics { From 474f3c335ccdfcc1932e24df06ee03dabd4f5481 Mon Sep 17 00:00:00 2001 From: Thijs van der Gugten Date: Sat, 15 Oct 2022 21:24:21 +0200 Subject: [PATCH 02/10] Remove hardcoded fields, review --- opennebula/resource_opennebula_template.go | 46 +++++++++---------- .../resource_opennebula_template_test.go | 6 +++ opennebula/shared_schemas.go | 45 +++++++++--------- 3 files changed, 51 insertions(+), 46 deletions(-) diff --git a/opennebula/resource_opennebula_template.go b/opennebula/resource_opennebula_template.go index 17b54a3f9..e5aa6007d 100644 --- a/opennebula/resource_opennebula_template.go +++ b/opennebula/resource_opennebula_template.go @@ -426,43 +426,39 @@ func resourceOpennebulaTemplateReadCustom(ctx context.Context, d *schema.Resourc d.Set("gname", tpl.GName) d.Set("group", tpl.GName) d.Set("reg_time", tpl.RegTime) - d.Set("description", "") - d.Set("sched_requirements", "") d.Set("permissions", permissionsUnixString(*tpl.Permissions)) - getTags := make(map[string]interface{}, 0) - for k, v := range pairsToMap(tpl.Template.Template) { - if k != "MEMORY" && k != "CPU" && k != "VCPU" && k != "VROUTER" && k != "DESCRIPTION" && k != "SCHED_REQUIREMENTS" { - getTags[strings.ToLower(k)] = v - } - } - d.Set("tags", getTags) - for _, value := range tpl.Template.Elements { - if pair, ok := value.(*dyn.Pair); ok { - switch pair.XMLName.Local { - case "DESCRIPTION", "SCHED_REQUIREMENTS": - d.Set(strings.ToLower(pair.XMLName.Local), pair.Value) - } - } if vector, ok := value.(*dyn.Vector); ok { - getOS := make(map[string]interface{}, 0) - switch vector.XMLName.Local { - case "OS", "FEATURES", "GRAPHICS", "CPU_MODEL": + getVector := make(map[string]interface{}, 0) + // In 'tpl.Template.Elements', there are uppercase keys, and in + // 'commonTemplateSchemas()' there are lower-case keys. + // In 'tpl.Template.Elements', there is a key 'CPU_MODEL', but in + // 'commonTemplateSchemas()' this key is called 'cpumodel'. + vector_key := strings.Replace(strings.ToLower(vector.XMLName.Local), "_", "", -1) + if _, inCommonSchema := commonTemplateSchemas()[vector_key]; !inCommonSchema { + continue + } + switch commonTemplateSchemas()[vector_key].Type.String() { + case "TypeList", "TypeSet": for _, pair := range vector.Pairs { - getOS[strings.ToLower(pair.XMLName.Local)] = pair.Value + getVector[strings.ToLower(pair.XMLName.Local)] = pair.Value } - d.Set(strings.Replace(strings.ToLower(vector.XMLName.Local), "_", "", -1), append(make([]interface{}, 0), getOS)) - case "CONTEXT": + + d.Set(vector_key, append(make([]interface{}, 0), getVector)) + case "TypeMap": for _, pair := range vector.Pairs { switch pair.XMLName.Local { case "SET_HOSTNAME", "NETWORK": - getOS[pair.XMLName.Local] = pair.Value + // In documentation about the resource 'opennebula_template', + // there are uppercase-keys in the context-field. For most other + // fields, the documentation uses lowercase-keys. + getVector[pair.XMLName.Local] = pair.Value default: - getOS[strings.ToLower(pair.XMLName.Local)] = pair.Value + getVector[strings.ToLower(pair.XMLName.Local)] = pair.Value } } - d.Set(strings.ToLower(vector.XMLName.Local), getOS) + d.Set(strings.ToLower(vector.XMLName.Local), getVector) } } } diff --git a/opennebula/resource_opennebula_template_test.go b/opennebula/resource_opennebula_template_test.go index 6a3cbc585..95672cc81 100644 --- a/opennebula/resource_opennebula_template_test.go +++ b/opennebula/resource_opennebula_template_test.go @@ -177,6 +177,7 @@ func TestAccTemplate(t *testing.T) { resource.TestCheckResourceAttr("opennebula_template.template", "tags.env", "dev"), resource.TestCheckResourceAttr("opennebula_template.template", "tags.customer", "test"), resource.TestCheckNoResourceAttr("opennebula_template.template", "tags.version"), + resource.TestCheckNoResourceAttr("opennebula_template.template", "features"), resource.TestCheckResourceAttrSet("opennebula_template.template", "uid"), resource.TestCheckResourceAttrSet("opennebula_template.template", "gid"), resource.TestCheckResourceAttrSet("opennebula_template.template", "uname"), @@ -193,6 +194,11 @@ func TestAccTemplate(t *testing.T) { ResourceName: "opennebula_template.template", ImportState: true, ImportStateVerify: true, + // The fields 'description' and 'sched_requirements' unfortunately need to be ignored during state-verify. + // During the first teststeps, these fields are defined, and in the last teststp, these fields are deleted. + // However, these fields are still present in the Terraform-state. For troubleshooting, note that + // d.State().Attributes["description"] and d.GetOk("description") give different results, where this may be unexpected. + ImportStateVerifyIgnore: []string{"description", "sched_requirements"}, }, }, }) diff --git a/opennebula/shared_schemas.go b/opennebula/shared_schemas.go index 83b838e34..f0d44a476 100644 --- a/opennebula/shared_schemas.go +++ b/opennebula/shared_schemas.go @@ -860,6 +860,8 @@ func flattenVMUserTemplate(d *schema.ResourceData, meta interface{}, vmTemplate // We read attributes only if they are described in the VM description // to avoid a diff due to template attribute inheritence + // However, when importing a Terraform-managed template from Opennebula, + // not all parameters can be expected to present in d. // add default_tags to tags_all config := meta.(*Configuration) @@ -878,17 +880,24 @@ func flattenVMUserTemplate(d *schema.ResourceData, meta interface{}, vmTemplate d.Set("default_tags", config.defaultTags) tags := make(map[string]interface{}) - // Get only tags described in the configuration - if tagsInterface, ok := d.GetOk("tags"); ok { - for k, _ := range tagsInterface.(map[string]interface{}) { - tagValue, err := vmTemplate.GetStr(strings.ToUpper(k)) - if err != nil { - return err - } - tags[k] = tagValue - tagsAll[k] = tagValue + // Read all tags in the template, and add them to d. + for element, _ := range vmTemplate.Elements { + pair, ok := vmTemplate.Elements[element].(*dynamic.Pair) + if !ok { + continue + } + + // The template 'vmTemplate' contains uppercase-keys, The + // common schema 'commonTemplateSchemas()' contains lowercase-keys. + // If a key in 'vmTemplate.Elements' is not contained in + // 'commonTemplateSchemas()', it is assumed the key is a tag. + if _, ok := commonTemplateSchemas()[strings.ToLower(pair.Key())]; !ok { + tags[strings.ToLower(pair.Key())] = pair.Value + tagsAll[strings.ToLower(pair.Key())] = pair.Value } + } + if len(tags) > 0 { err := d.Set("tags", tags) if err != nil { return err @@ -901,10 +910,8 @@ func flattenVMUserTemplate(d *schema.ResourceData, meta interface{}, vmTemplate d.Set("tags_all", tagsAll) - schedReqCfg := d.Get("sched_requirements").(string) - - if len(schedReqCfg) > 0 { - schedReq, err := vmTemplate.GetStr("SCHED_REQUIREMENTS") + schedReq, err := vmTemplate.GetStr("SCHED_REQUIREMENTS") + if len(schedReq) > 0 { if err == nil { err = d.Set("sched_requirements", schedReq) if err != nil { @@ -913,10 +920,8 @@ func flattenVMUserTemplate(d *schema.ResourceData, meta interface{}, vmTemplate } } - schedDSReqCfg := d.Get("sched_ds_requirements").(string) - - if len(schedDSReqCfg) > 0 { - schedDSReq, err := vmTemplate.GetStr("SCHED_DS_REQUIREMENTS") + schedDSReq, err := vmTemplate.GetStr("SCHED_DS_REQUIREMENTS") + if len(schedDSReq) > 0 { if err == nil { err = d.Set("sched_ds_requirements", schedDSReq) if err != nil { @@ -925,10 +930,8 @@ func flattenVMUserTemplate(d *schema.ResourceData, meta interface{}, vmTemplate } } - descriptionCfg := d.Get("description").(string) - - if len(descriptionCfg) > 0 { - description, err := vmTemplate.GetStr("DESCRIPTION") + description, err := vmTemplate.GetStr("DESCRIPTION") + if len(description) > 0 { if err == nil { err = d.Set("description", description) if err != nil { From 149703cd03b94942863bfb25c07d78d078327fef Mon Sep 17 00:00:00 2001 From: Alex <12645087+lzadjsf@users.noreply.github.com> Date: Fri, 9 Dec 2022 17:45:14 +0300 Subject: [PATCH 03/10] Update template.html.markdown FIX: typo - letter order in vCPU abbreviation --- website/docs/r/template.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/template.html.markdown b/website/docs/r/template.html.markdown index 4ce89b630..0c3cef070 100644 --- a/website/docs/r/template.html.markdown +++ b/website/docs/r/template.html.markdown @@ -88,7 +88,7 @@ The following arguments are supported: * `permissions` - (Optional) Permissions applied on template. Defaults to the UMASK in OpenNebula (in UNIX Format: owner-group-other => Use-Manage-Admin). * `group` - (Optional) Name of the group which owns the template. Defaults to the caller primary group. * `cpu` - (Optional) Amount of CPU shares assigned to the VM. **Mandatory if `template_****id` is not set**. -* `vpcu` - (Optional) Number of CPU cores presented to the VM. +* `vcpu` - (Optional) Number of CPU cores presented to the VM. * `memory` - (Optional) Amount of RAM assigned to the VM in MB. **Mandatory if `template_****id` is not set**. * `features` - (Optional) See [Features parameters](#features-parameters) below for details. * `context` - (Optional) Array of free form key=value pairs, rendered and added to the CONTEXT variables for the VM. Recommended to include: `NETWORK = "YES"` and `SET_HOSTNAME = "$NAME"`. From 039784aea320218ebf055ed8138b2c153728babe Mon Sep 17 00:00:00 2001 From: Pierre Lafievre Date: Fri, 16 Dec 2022 11:27:51 +0100 Subject: [PATCH 04/10] B #382: fix datastore system type --- CHANGELOG.md | 6 ++++++ opennebula/resource_opennebula_datastore.go | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08c7f9eaa..6802b6105 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.1.1 (Unreleased) + +BUG FIXES: + +* resources/opennebula_datastore: fix system type values (#382) + # 1.1.0 (December 6th, 2022) FEATURES: diff --git a/opennebula/resource_opennebula_datastore.go b/opennebula/resource_opennebula_datastore.go index 7846e675c..03c8fe35b 100644 --- a/opennebula/resource_opennebula_datastore.go +++ b/opennebula/resource_opennebula_datastore.go @@ -18,7 +18,7 @@ import ( var datastoreTypes = map[string]string{ "IMAGE": "IMAGE_DS", - "SYSTEM": "SYSTEM_IMAGE", + "SYSTEM": "SYSTEM_DS", "FILE": "FILE_DS"} func resourceOpennebulaDatastore() *schema.Resource { @@ -186,7 +186,7 @@ func resourceOpennebulaDatastore() *schema.Resource { Schema: map[string]*schema.Schema{ "datastore": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, Description: "Datastore driver", }, @@ -311,8 +311,8 @@ func resourceOpennebulaDatastoreCreate(ctx context.Context, d *schema.ResourceDa } else if len(customAttrsList) > 0 { customAttrsMap := customAttrsList[0].(map[string]interface{}) - datastoreDriver, ok := customAttrsMap["datastore"] - if ok { + datastoreDriver, _ := customAttrsMap["datastore"] + if len(datastoreDriver.(string)) > 0 { tpl.Add("DS_MAD", datastoreDriver) } transferDriver, ok := customAttrsMap["transfer"] From 5de51191380ea5104b0f22d99f1f162fed0a2428 Mon Sep 17 00:00:00 2001 From: Pierre Lafievre Date: Fri, 16 Dec 2022 16:47:55 +0100 Subject: [PATCH 05/10] B #385: fix host types case --- CHANGELOG.md | 1 + opennebula/resource_opennebula_host.go | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6802b6105..5ee6d9a50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ BUG FIXES: * resources/opennebula_datastore: fix system type values (#382) +* resources/opennebula_host: fix host resource type case (#385) # 1.1.0 (December 6th, 2022) diff --git a/opennebula/resource_opennebula_host.go b/opennebula/resource_opennebula_host.go index deb8a1272..a8c91ea18 100644 --- a/opennebula/resource_opennebula_host.go +++ b/opennebula/resource_opennebula_host.go @@ -19,7 +19,7 @@ import ( hostk "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/host/keys" ) -var hostTypes = []string{"KVM", "QEMU", "LXD", "LXC", "FIRECRACKER", "VCENTER", "CUSTOM"} +var hostTypes = []string{"kvm", "qemu", "lxd", "lxc", "firecracker", "vcenter", "custom"} var defaultHostMinTimeout = 20 var defaultHostTimeout = time.Duration(defaultHostMinTimeout) * time.Minute @@ -49,9 +49,8 @@ func resourceOpennebulaHost() *schema.Resource { ForceNew: true, Description: "Type of the new host: kvm, qemu, lxd, lxc, firecracker, custom", ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - value := strings.ToUpper(v.(string)) - if inArray(value, hostTypes) < 0 { + if inArray(v.(string), hostTypes) < 0 { errors = append(errors, fmt.Errorf("host \"type\" must be one of: %s", strings.Join(hostTypes, ","))) } @@ -128,22 +127,22 @@ func resourceOpennebulaHostCreate(ctx context.Context, d *schema.ResourceData, m var diags diag.Diagnostics name := d.Get("name").(string) - hostType := strings.ToUpper(d.Get("type").(string)) + hostType := d.Get("type").(string) var vmMad, imMad string switch hostType { - case "KVM", "QEMU", "LXD", "LXC", "FIRECRACKER": + case "kvm", "qemu", "lxd", "lxc", "firecracker": imMad = hostType vmMad = hostType - case "VCENTER": + case "vcenter": diags = append(diags, diag.Diagnostic{ Severity: diag.Error, - Summary: "The VCENTER type is not managed.", + Summary: "The vcenter type is not managed.", }) return diags - case "CUSTOM": + case "custom": madsList := d.Get("custom").(*schema.Set).List() From e0d077e3c718336d9952ab2f77f2c6ba1bd55694 Mon Sep 17 00:00:00 2001 From: Thijs van der Gugten Date: Thu, 12 Jan 2023 19:23:57 +0100 Subject: [PATCH 06/10] Merge from upstream --- CHANGELOG.md | 4 ++ opennebula/resource_opennebula_template.go | 4 +- .../resource_opennebula_template_vm_group.go | 1 - .../resource_opennebula_virtual_machine.go | 31 +++++++--- ...urce_opennebula_virtual_router_instance.go | 15 +++-- opennebula/shared_schemas.go | 61 +++++++++++-------- website/docs/r/virtual_machine.html.markdown | 3 +- .../docs/r/virtual_router_instance.markdown | 1 + 8 files changed, 79 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ee6d9a50..a03fd5faf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ BUG FIXES: * resources/opennebula_datastore: fix system type values (#382) * resources/opennebula_host: fix host resource type case (#385) +* resources/opennebula_virtual_machine: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) +* resources/opennebula_virtual_router_instance: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) +* resources/opennebula_template: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) +* resources/opennebula_virtual_router_instance_template: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) # 1.1.0 (December 6th, 2022) diff --git a/opennebula/resource_opennebula_template.go b/opennebula/resource_opennebula_template.go index f1e97eeec..296fe8cd0 100644 --- a/opennebula/resource_opennebula_template.go +++ b/opennebula/resource_opennebula_template.go @@ -485,7 +485,7 @@ func resourceOpennebulaTemplateReadCustom(ctx context.Context, d *schema.Resourc } } - err = flattenTemplate(d, &tpl.Template) + err = flattenTemplate(d, nil, &tpl.Template) if err != nil { diags = append(diags, diag.Diagnostic{ Severity: diag.Error, @@ -495,7 +495,7 @@ func resourceOpennebulaTemplateReadCustom(ctx context.Context, d *schema.Resourc return diags } - err = flattenVMUserTemplate(d, meta, &tpl.Template.Template) + err = flattenVMUserTemplate(d, meta, nil, &tpl.Template.Template) if err != nil { diags = append(diags, diag.Diagnostic{ Severity: diag.Error, diff --git a/opennebula/resource_opennebula_template_vm_group.go b/opennebula/resource_opennebula_template_vm_group.go index 9519c6bce..f35bf3c84 100644 --- a/opennebula/resource_opennebula_template_vm_group.go +++ b/opennebula/resource_opennebula_template_vm_group.go @@ -548,7 +548,6 @@ func resourceOpennebulaVMGroupUpdate(ctx context.Context, d *schema.ResourceData update = true } - log.Printf("[DEBUG] === 3 newTpl: %s", newTpl.String()) if update { err = vmgc.Update(newTpl.String(), int(parameters.Replace)) diff --git a/opennebula/resource_opennebula_virtual_machine.go b/opennebula/resource_opennebula_virtual_machine.go index 27226b171..f5ed79b4c 100644 --- a/opennebula/resource_opennebula_virtual_machine.go +++ b/opennebula/resource_opennebula_virtual_machine.go @@ -64,11 +64,6 @@ func resourceOpennebulaVirtualMachine() *schema.Resource { ForceNew: true, Description: "Id of the VM template to use. Defaults to -1: no template used.", }, - "template_tags": { - Type: schema.TypeMap, - Computed: true, - Description: "When template_id was set this keeps the template tags.", - }, "template_nic": templateNICVMSchema(), }, ), @@ -326,6 +321,16 @@ func resourceOpennebulaVirtualMachineCreate(ctx context.Context, d *schema.Resou d.Set("template_tags", inheritedTags) + // save inherited template sections names + inheritedSectionsNames := make(map[string]interface{}) + for _, e := range tpl.Template.Elements { + if vec, ok := e.(*dyn.Vector); ok { + inheritedSectionsNames[vec.Key()] = "" + } + } + + d.Set("template_section_names", inheritedSectionsNames) + } else { if _, ok := d.GetOk("cpu"); !ok { @@ -372,6 +377,7 @@ func resourceOpennebulaVirtualMachineCreate(ctx context.Context, d *schema.Resou } d.Set("template_tags", nil) + d.Set("template_section_names", map[string]interface{}{}) } d.SetId(fmt.Sprintf("%v", vmID)) @@ -564,7 +570,12 @@ func resourceOpennebulaVirtualMachineReadCustom(ctx context.Context, d *schema.R } } - err = flattenTemplate(d, &vm.Template) + var inheritedVectors map[string]interface{} + inheritedVectorsIf := d.Get("template_section_names") + if inheritedVectorsIf != nil { + inheritedVectors = inheritedVectorsIf.(map[string]interface{}) + } + err = flattenTemplate(d, inheritedVectors, &vm.Template) if err != nil { diags = append(diags, diag.Diagnostic{ Severity: diag.Error, @@ -574,7 +585,13 @@ func resourceOpennebulaVirtualMachineReadCustom(ctx context.Context, d *schema.R return diags } - err = flattenVMUserTemplate(d, meta, &vm.UserTemplate.Template) + var inheritedTags map[string]interface{} + inheritedTagsIf := d.Get("template_tags") + if inheritedTagsIf != nil { + inheritedTags = inheritedTagsIf.(map[string]interface{}) + } + + err = flattenVMUserTemplate(d, meta, inheritedTags, &vm.UserTemplate.Template) if err != nil { diags = append(diags, diag.Diagnostic{ Severity: diag.Error, diff --git a/opennebula/resource_opennebula_virtual_router_instance.go b/opennebula/resource_opennebula_virtual_router_instance.go index 098a065cc..f6f5b6c8e 100644 --- a/opennebula/resource_opennebula_virtual_router_instance.go +++ b/opennebula/resource_opennebula_virtual_router_instance.go @@ -45,11 +45,6 @@ func resourceOpennebulaVirtualRouterInstance() *schema.Resource { Required: true, Description: "Identifier of the parent virtual router ressource", }, - "template_tags": { - Type: schema.TypeMap, - Computed: true, - Description: "When template_id was set this keeps the template tags.", - }, }, ), } @@ -175,6 +170,16 @@ func resourceOpennebulaVirtualRouterInstanceCreate(ctx context.Context, d *schem d.Set("template_tags", inheritedTags) + // save inherited template sections names + inheritedSectionsNames := make(map[string]interface{}) + for _, e := range tpl.Template.Elements { + if vec, ok := e.(*dyn.Vector); ok { + inheritedSectionsNames[vec.Key()] = "" + } + } + + d.Set("template_section_names", inheritedSectionsNames) + vrInfos, err = vrc.Info(false) if err != nil { diags = append(diags, diag.Diagnostic{ diff --git a/opennebula/shared_schemas.go b/opennebula/shared_schemas.go index 087186a34..8a04647ca 100644 --- a/opennebula/shared_schemas.go +++ b/opennebula/shared_schemas.go @@ -68,6 +68,16 @@ func commonVMSchemas() map[string]*schema.Schema { Default: false, Description: "Immediately poweroff/terminate/reboot/undeploy the VM. (default: false)", }, + "template_tags": { + Type: schema.TypeMap, + Computed: true, + Description: "When template_id was set this keeps the template tags.", + }, + "template_section_names": { + Type: schema.TypeMap, + Computed: true, + Description: "When template_id was set this keeps the template sections names.", + }, }, ) } @@ -740,7 +750,7 @@ func flattenTemplateVMGroup(d *schema.ResourceData, vmTemplate *vm.Template) err return nil } -func flattenTemplate(d *schema.ResourceData, vmTemplate *vm.Template) error { +func flattenTemplate(d *schema.ResourceData, inheritedVectors map[string]interface{}, vmTemplate *vm.Template) error { var err error @@ -796,7 +806,8 @@ func flattenTemplate(d *schema.ResourceData, vmTemplate *vm.Template) error { cpumodelMap = append(cpumodelMap, map[string]interface{}{ "model": cpumodel, }) - if _, ok := d.GetOk("cpumodel"); ok { + _, inherited := inheritedVectors["CPU_MODEL"] + if !inherited { err = d.Set("cpumodel", cpumodelMap) if err != nil { return err @@ -815,7 +826,8 @@ func flattenTemplate(d *schema.ResourceData, vmTemplate *vm.Template) error { "arch": arch, "boot": boot, }) - if _, ok := d.GetOk("os"); ok { + _, inherited := inheritedVectors["OS"] + if !inherited { err = d.Set("os", osMap) if err != nil { return err @@ -831,7 +843,8 @@ func flattenTemplate(d *schema.ResourceData, vmTemplate *vm.Template) error { "type": t, "keymap": keymap, }) - if _, ok := d.GetOk("graphics"); ok { + _, inherited := inheritedVectors["GRAPHICS"] + if !inherited { err = d.Set("graphics", graphMap) if err != nil { return err @@ -851,7 +864,8 @@ func flattenTemplate(d *schema.ResourceData, vmTemplate *vm.Template) error { "virtio_scsi_queues": virtio_scsi_queues, "iothreads": iothreads, }) - if _, ok := d.GetOk("features"); ok { + _, inherited := inheritedVectors["FEATURES"] + if !inherited { err = d.Set("features", featuresMap) if err != nil { return err @@ -862,7 +876,7 @@ func flattenTemplate(d *schema.ResourceData, vmTemplate *vm.Template) error { return nil } -func flattenVMUserTemplate(d *schema.ResourceData, meta interface{}, vmTemplate *dynamic.Template) error { +func flattenVMUserTemplate(d *schema.ResourceData, meta interface{}, inheritedTags map[string]interface{}, vmTemplate *dynamic.Template) error { // We read attributes only if they are described in the VM description // to avoid a diff due to template attribute inheritence @@ -922,32 +936,29 @@ func flattenVMUserTemplate(d *schema.ResourceData, meta interface{}, vmTemplate d.Set("tags_all", tagsAll) schedReq, err := vmTemplate.GetStr("SCHED_REQUIREMENTS") - if len(schedReq) > 0 { - if err == nil { - err = d.Set("sched_requirements", schedReq) - if err != nil { - return err - } + _, inherited := inheritedTags["SCHED_REQUIREMENTS"] + if !inherited { + err = d.Set("sched_requirements", schedReq) + if err != nil { + return err } } schedDSReq, err := vmTemplate.GetStr("SCHED_DS_REQUIREMENTS") - if len(schedDSReq) > 0 { - if err == nil { - err = d.Set("sched_ds_requirements", schedDSReq) - if err != nil { - return err - } + _, inherited = inheritedTags["SCHED_DS_REQUIREMENTS"] + if !inherited { + err = d.Set("sched_ds_requirements", schedDSReq) + if err != nil { + return err } } - description, err := vmTemplate.GetStr("DESCRIPTION") - if len(description) > 0 { - if err == nil { - err = d.Set("description", description) - if err != nil { - return err - } + description, _ := vmTemplate.GetStr("DESCRIPTION") + _, inherited = inheritedTags["DESCRIPTION"] + if !inherited { + err = d.Set("description", description) + if err != nil { + return err } } diff --git a/website/docs/r/virtual_machine.html.markdown b/website/docs/r/virtual_machine.html.markdown index a7e5f8190..7f5e30fa3 100644 --- a/website/docs/r/virtual_machine.html.markdown +++ b/website/docs/r/virtual_machine.html.markdown @@ -184,7 +184,8 @@ The following attribute are exported: * `template_nic` - when `template_id` is used and the template define some NICs, this contains the template NICs description. * `tags_all` - Result of the applied `default_tags` and then resource `tags`. * `default_tags` - Default tags defined in the provider configuration. -* `template_tags` - When template_id was set this keeps the template tags. +* `template_tags` - When `template_id` was set this keeps the template tags. +* `template_section_names` - When `template_id` was set this keeps the template section names only. ### Template NIC diff --git a/website/docs/r/virtual_router_instance.markdown b/website/docs/r/virtual_router_instance.markdown index 6bf4e53e6..db64a0da1 100644 --- a/website/docs/r/virtual_router_instance.markdown +++ b/website/docs/r/virtual_router_instance.markdown @@ -163,6 +163,7 @@ The following attribute are exported: * `tags_all` - Result of the applied `default_tags` and then resource `tags`. * `default_tags` - Default tags defined in the provider configuration. * `template_tags` - When `template_id` was set this keeps the template tags. +* `template_section_names` - When `template_id` was set this keeps the template section names only. ### Template disk From 29981c62e71fe709d6f3b6b364fb9a9ea6474a63 Mon Sep 17 00:00:00 2001 From: Pierre Lafievre Date: Wed, 14 Dec 2022 15:50:39 +0100 Subject: [PATCH 07/10] B #312: less null values --- CHANGELOG.md | 6 ++++-- opennebula/resource_opennebula_virtual_machine.go | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a03fd5faf..57294c2a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,12 @@ BUG FIXES: * resources/opennebula_datastore: fix system type values (#382) * resources/opennebula_host: fix host resource type case (#385) -* resources/opennebula_virtual_machine: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) -* resources/opennebula_virtual_router_instance: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) +* resources/opennebula_virtual_machine: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description`, `template_id` (#377, #312) +* resources/opennebula_virtual_router_instance: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description`, `template_id` (#377, #312) * resources/opennebula_template: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) * resources/opennebula_virtual_router_instance_template: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) +* resources/opennebula_virtual_machine: set empty values instead of null for `template_disk`, `template_nic` (#312) +* resources/opennebula_virtual_router_instance: set empty values instead of null for `template_disk`, `template_nic` (#312) # 1.1.0 (December 6th, 2022) diff --git a/opennebula/resource_opennebula_virtual_machine.go b/opennebula/resource_opennebula_virtual_machine.go index f5ed79b4c..893fd2fa0 100644 --- a/opennebula/resource_opennebula_virtual_machine.go +++ b/opennebula/resource_opennebula_virtual_machine.go @@ -613,6 +613,18 @@ func resourceOpennebulaVirtualMachineRead(ctx context.Context, d *schema.Resourc var diags diag.Diagnostics + // read template ID from which the VM was created + templateID, _ := vmInfos.Template.GetInt("TEMPLATE_ID") + d.Set("template_id", templateID) + + // add empty values for import + if _, ok := d.GetOk("template_disk"); !ok { + d.Set("template_disk", []interface{}{}) + } + if _, ok := d.GetOk("template_nic"); !ok { + d.Set("template_nic", []interface{}{}) + } + err := flattenVMDisk(d, &vmInfos.Template) if err != nil { diags = append(diags, diag.Diagnostic{ From 796e718ed62ee35c86d9e540ad326ca82fc7b94c Mon Sep 17 00:00:00 2001 From: Pierre Lafievre Date: Wed, 14 Dec 2022 15:51:38 +0100 Subject: [PATCH 08/10] B #369: fill template_tags with empty value --- CHANGELOG.md | 4 ++-- opennebula/resource_opennebula_virtual_machine.go | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57294c2a3..840bccdb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,8 @@ BUG FIXES: * resources/opennebula_virtual_router_instance: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description`, `template_id` (#377, #312) * resources/opennebula_template: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) * resources/opennebula_virtual_router_instance_template: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) -* resources/opennebula_virtual_machine: set empty values instead of null for `template_disk`, `template_nic` (#312) -* resources/opennebula_virtual_router_instance: set empty values instead of null for `template_disk`, `template_nic` (#312) +* resources/opennebula_virtual_machine: set empty values instead of null for `template_disk`, `template_nic`, `template_tags` (#312, #369) +* resources/opennebula_virtual_router_instance: set empty values instead of null for `template_disk`, `template_nic`, `template_tags` (#312, #369) # 1.1.0 (December 6th, 2022) diff --git a/opennebula/resource_opennebula_virtual_machine.go b/opennebula/resource_opennebula_virtual_machine.go index 893fd2fa0..e7e8e6256 100644 --- a/opennebula/resource_opennebula_virtual_machine.go +++ b/opennebula/resource_opennebula_virtual_machine.go @@ -376,7 +376,7 @@ func resourceOpennebulaVirtualMachineCreate(ctx context.Context, d *schema.Resou return diags } - d.Set("template_tags", nil) + d.Set("template_tags", map[string]interface{}{}) d.Set("template_section_names", map[string]interface{}{}) } @@ -624,6 +624,9 @@ func resourceOpennebulaVirtualMachineRead(ctx context.Context, d *schema.Resourc if _, ok := d.GetOk("template_nic"); !ok { d.Set("template_nic", []interface{}{}) } + if _, ok := d.GetOk("template_tags"); !ok { + d.Set("template_tags", map[string]interface{}{}) + } err := flattenVMDisk(d, &vmInfos.Template) if err != nil { From b1cf5b76d64a4d486c7d8ed26dd7f0c9c49de035 Mon Sep 17 00:00:00 2001 From: Pierre Lafievre Date: Tue, 10 Jan 2023 17:07:48 +0100 Subject: [PATCH 09/10] fix doc --- opennebula/resource_opennebula_group_admins.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opennebula/resource_opennebula_group_admins.go b/opennebula/resource_opennebula_group_admins.go index c5376fd7b..105d4f094 100644 --- a/opennebula/resource_opennebula_group_admins.go +++ b/opennebula/resource_opennebula_group_admins.go @@ -24,7 +24,7 @@ func resourceOpennebulaGroupAdmins() *schema.Resource { Type: schema.TypeInt, Required: true, ForceNew: true, - Description: "Name of the group", + Description: "ID of the group", }, "users_ids": { Type: schema.TypeSet, @@ -191,7 +191,7 @@ func resourceOpennebulaGroupAdminsDelete(ctx context.Context, d *schema.Resource } gc := controller.Group(int(groupID)) - // add admins users_ids if list provided + // remove admins users_ids if list provided adminsIDs := d.Get("users_ids").(*schema.Set).List() for _, id := range adminsIDs { err := gc.DelAdmin(id.(int)) From d229fa4b7ce5ad804066e1aeaefbbf76abd7521f Mon Sep 17 00:00:00 2001 From: Pierre Lafievre Date: Wed, 11 Jan 2023 15:23:51 +0100 Subject: [PATCH 10/10] B #389: manage cluster membership from cluster resource --- CHANGELOG.md | 9 +++++++++ opennebula/resource_opennebula_datastore.go | 10 ++++++++++ opennebula/resource_opennebula_host.go | 7 +++++++ opennebula/resource_opennebula_host_test.go | 6 ------ opennebula/resource_opennebula_virtual_network.go | 3 ++- website/docs/r/datastore.html.markdown | 3 ++- website/docs/r/host.html.markdown | 4 ++-- website/docs/r/virtual_network.html.markdown | 3 +-- 8 files changed, 33 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 840bccdb7..87a2e15a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,15 @@ BUG FIXES: * resources/opennebula_virtual_router_instance_template: import more sections and attributes: `os`, `graphics`, `cpu_model`, `features`, `sched_requirements`, `sched_ds_requirements`, `description` (#377) * resources/opennebula_virtual_machine: set empty values instead of null for `template_disk`, `template_nic`, `template_tags` (#312, #369) * resources/opennebula_virtual_router_instance: set empty values instead of null for `template_disk`, `template_nic`, `template_tags` (#312, #369) +* resources/opennebula_host: add computed `cluster` attribute. (#389) +* resources/opennebula_datastore: add computed `clusters` attribute. (#389) + +DEPRECATION: + +* resources/opennebula_host: deprecate `cluster_id` (#389) +* resources/opennebula_datastore: deprecate `cluster_id` (#389) +* resources/opennebula_virtual_network: deprecate `clusters` (#389) + # 1.1.0 (December 6th, 2022) diff --git a/opennebula/resource_opennebula_datastore.go b/opennebula/resource_opennebula_datastore.go index 03c8fe35b..1ae37be8b 100644 --- a/opennebula/resource_opennebula_datastore.go +++ b/opennebula/resource_opennebula_datastore.go @@ -61,6 +61,15 @@ func resourceOpennebulaDatastore() *schema.Resource { Optional: true, Default: -1, Description: "ID of the cluster", + Deprecated: "manage membership from the datastores attribute of the cluster", + }, + "clusters": { + Type: schema.TypeSet, + Computed: true, + Description: "List of cluster IDs hosting the datastore", + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, }, "restricted_directories": { Type: schema.TypeString, @@ -450,6 +459,7 @@ func resourceOpennebulaDatastoreRead(ctx context.Context, d *schema.ResourceData } d.Set("cluster_id", id) } + d.Set("clusters", datastoreInfos.Clusters.ID) restrictedDirs, err := datastoreInfos.Template.Get(dsKey.RestrictedDirs) if err == nil { diff --git a/opennebula/resource_opennebula_host.go b/opennebula/resource_opennebula_host.go index a8c91ea18..2930744ce 100644 --- a/opennebula/resource_opennebula_host.go +++ b/opennebula/resource_opennebula_host.go @@ -100,6 +100,12 @@ func resourceOpennebulaHost() *schema.Resource { Optional: true, Default: -1, Description: "ID of the cluster", + Deprecated: "manage membership from the hosts attribute of the cluster", + }, + "cluster": { + Type: schema.TypeInt, + Computed: true, + Description: "Cluster IDs hosting the host", }, "tags": tagsSchema(), "default_tags": defaultTagsSchemaComputed(), @@ -312,6 +318,7 @@ func resourceOpennebulaHostRead(ctx context.Context, d *schema.ResourceData, met d.SetId(fmt.Sprintf("%v", hostInfos.ID)) d.Set("name", hostInfos.Name) + d.Set("cluster", hostInfos.ClusterID) tags := make(map[string]interface{}) tagsAll := make(map[string]interface{}) diff --git a/opennebula/resource_opennebula_host_test.go b/opennebula/resource_opennebula_host_test.go index 56a21eed3..f3cc2f8d4 100644 --- a/opennebula/resource_opennebula_host_test.go +++ b/opennebula/resource_opennebula_host_test.go @@ -24,7 +24,6 @@ func TestAccHost(t *testing.T) { "virtualization": "dummy", "information": "dummy", }), - resource.TestCheckResourceAttr("opennebula_host.test1", "cluster_id", "0"), resource.TestCheckResourceAttr("opennebula_host.test1", "tags.%", "2"), resource.TestCheckResourceAttr("opennebula_host.test1", "tags.environment", "example"), resource.TestCheckResourceAttr("opennebula_host.test1", "tags.test", "test"), @@ -35,7 +34,6 @@ func TestAccHost(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("opennebula_host.test1", "name", "test-updated"), resource.TestCheckResourceAttr("opennebula_host.test1", "type", "custom"), - resource.TestCheckResourceAttr("opennebula_host.test1", "cluster_id", "0"), resource.TestCheckTypeSetElemNestedAttrs("opennebula_host.test1", "custom.*", map[string]string{ "virtualization": "dummy", "information": "dummy", @@ -54,7 +52,6 @@ func TestAccHost(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("opennebula_host.test1", "name", "test-updated"), resource.TestCheckResourceAttr("opennebula_host.test1", "type", "custom"), - resource.TestCheckResourceAttr("opennebula_host.test1", "cluster_id", "0"), resource.TestCheckTypeSetElemNestedAttrs("opennebula_host.test1", "custom.*", map[string]string{ "virtualization": "dummy", "information": "dummy", @@ -95,7 +92,6 @@ var testAccHostConfig = ` resource "opennebula_host" "test1" { name = "test-custom" type = "custom" - cluster_id = 0 custom { virtualization = "dummy" @@ -113,7 +109,6 @@ var testAccHostConfigAddOvercommit = ` resource "opennebula_host" "test1" { name = "test-updated" type = "custom" - cluster_id = 0 custom { virtualization = "dummy" @@ -136,7 +131,6 @@ var testAccHostConfigUpdate = ` resource "opennebula_host" "test1" { name = "test-updated" type = "custom" - cluster_id = 0 custom { virtualization = "dummy" diff --git a/opennebula/resource_opennebula_virtual_network.go b/opennebula/resource_opennebula_virtual_network.go index 84026c749..123698246 100644 --- a/opennebula/resource_opennebula_virtual_network.go +++ b/opennebula/resource_opennebula_virtual_network.go @@ -136,11 +136,12 @@ func resourceOpennebulaVirtualNetwork() *schema.Resource { Type: schema.TypeSet, Optional: true, Computed: true, - Description: "List of cluster IDs hosting the virtual Network, if not set it uses the default cluster", + Description: "List of cluster IDs hosting the virtual Network", ConflictsWith: []string{"reservation_vnet", "reservation_size", "reservation_ar_id", "reservation_first_ip"}, Elem: &schema.Schema{ Type: schema.TypeInt, }, + Deprecated: "manage membership from the virtual_networks attribute of the cluster", }, "vlan_id": { Type: schema.TypeString, diff --git a/website/docs/r/datastore.html.markdown b/website/docs/r/datastore.html.markdown index 2cba60fc5..70b53826b 100644 --- a/website/docs/r/datastore.html.markdown +++ b/website/docs/r/datastore.html.markdown @@ -38,7 +38,7 @@ The following arguments are supported: * `name` - (Required) The name of the datastore. * `type` - (Required) Type of the new datastore: image, system, file. -* `cluster_id` - (Optional) ID of the cluster the datastore is part of. +* `cluster_id` - (Deprecated) ID of the cluster the datastore is part of. * `restricted_directories` - (Optional) Paths that cannot be used to register images. A space separated list of paths. * `safe_directories` - (Optional) If you need to allow a directory listed under RESTRICTED_DIRS. A space separated list of paths. * `no_decompress` - (Optional) Boolean, do not try to untar or decompress the file to be registered. @@ -86,6 +86,7 @@ The following attributes are exported: * `id` - ID of the datastore. * `tags_all` - Result of the applied `default_tags` and then resource `tags`. * `default_tags` - Default tags defined in the provider configuration. +* `clusters` - List of cluster IDs hosting the datastore. Manager cluster membership from `datastores` fields of the `cluster` resource instead. ## Import diff --git a/website/docs/r/host.html.markdown b/website/docs/r/host.html.markdown index 9b8b84893..ef5dcc163 100644 --- a/website/docs/r/host.html.markdown +++ b/website/docs/r/host.html.markdown @@ -40,7 +40,6 @@ Create a custom host: resource "opennebula_host" "example" { name = "test-kvm" type = "custom" - cluster_id = 0 custom = { virtualization = "custom" @@ -60,7 +59,7 @@ The following arguments are supported: * `name` - (Required) The name of the host. * `type` - (Required) Type of the new host: kvm, qemu, lxd, lxc, firecracker, custom. For now vcenter type is not managed by the provider. -* `cluster_id` - (Optional) ID of the cluster the host is part of. +* `cluster_id` - (Deprecated) ID of the cluster the host is part of. * `custom` - (Optional) If `type="custom"` this section should be defined, see [Custom](#custom) section for details. * `overcommit` - (Optional) This section allow to increase the allocatable capacity of the host. See [Overcommit](#overcommit) * `tags` - (Optional) Host tags (Key = value) @@ -84,6 +83,7 @@ The following attributes are exported: * `id` - ID of the host. * `tags_all` - Result of the applied `default_tags` and then resource `tags`. * `default_tags` - Default tags defined in the provider configuration. +* `cluster` - ID of the cluster hosting the host. Manager cluster membership from `hosts` fields of the `cluster` resource instead. ## Import diff --git a/website/docs/r/virtual_network.html.markdown b/website/docs/r/virtual_network.html.markdown index 86304707b..182268086 100644 --- a/website/docs/r/virtual_network.html.markdown +++ b/website/docs/r/virtual_network.html.markdown @@ -45,7 +45,6 @@ resource "opennebula_virtual_network" "example" { dns = "172.16.100.1" gateway = "172.16.100.1" security_groups = [0] - clusters = [0] ar { ar_type = "IP4" @@ -81,7 +80,7 @@ The following arguments are supported: * `bridge` - (Optional) Name of the bridge interface to which the virtual network should be associated. Conflicts with `reservation_vnet` and `reservation_size`. * `physical_device` - (Optional) Name of the physical device interface to which the virtual network should be associated. Conflicts with `reservation_vnet` and `reservation_size`. * `type` - (Optional) Virtual network type. One of these: `dummy`, `bridge`'`fw`, `ebtables`, `802.1Q`, `vxlan` or `ovswitch`. Defaults to `bridge`. Conflicts with `reservation_vnet` and `reservation_size`. -* `clusters` - (Optional) List of cluster IDs where the virtual network can be use. Conflicts with `reservation_vnet` and `reservation_size`. +* `clusters` - (Deprecated) List of cluster IDs where the virtual network can be use. Conflicts with `reservation_vnet` and `reservation_size`. Manager cluster membership from `virtual_networks` fields of the `cluster` resource instead. * `vlan_id` - (Optional) ID of VLAN. Only if `type` is `802.1Q`, `vxlan` or `ovswitch`. Conflicts with `reservation_vnet`, `reservation_size` and `automatic_vlan_id`. * `automatic_vlan_id` - (Optional) Flag to let OpenNebula scheduler to attribute the VLAN ID. Conflicts with `reservation_vnet`, `reservation_size` and `vlan_id`. * `mtu` - (Optional) Virtual network MTU. Defaults to `1500`. Conflicts with `reservation_vnet` and `reservation_size`.