diff --git a/CHANGELOG.md b/CHANGELOG.md index 69c9ea6c5..0a3060ded 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ FEATURES: * **New Resource**: `opennebula_cluster` (#227) +* resources/opennebula_group: add `template_section` to manage vectors with an unique key (#359) DEPRECATION: diff --git a/opennebula/resource_opennebula_group.go b/opennebula/resource_opennebula_group.go index 09b51b439..7cecc6368 100644 --- a/opennebula/resource_opennebula_group.go +++ b/opennebula/resource_opennebula_group.go @@ -85,6 +85,26 @@ func resourceOpennebulaGroup() *schema.Resource { "tags": tagsSchema(), "default_tags": defaultTagsSchemaComputed(), "tags_all": tagsSchemaComputed(), + "template_section": { + Type: schema.TypeList, + Optional: true, + Description: "Add custom section to the resource", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "tags": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, }, } } @@ -198,6 +218,18 @@ func resourceOpennebulaGroupCreate(ctx context.Context, d *schema.ResourceData, tpl.Elements = append(tpl.Elements, sunstoneVec) } + vectorsInterface := d.Get("template_section").([]interface{}) + for _, vectorIf := range vectorsInterface { + vector := vectorIf.(map[string]interface{}) + vecName := strings.ToUpper(vector["name"].(string)) + vecTags := vector["tags"].(map[string]interface{}) + + vec := tpl.AddVector(strings.ToUpper(vecName)) + for k, v := range vecTags { + vec.AddPair(k, v) + } + } + tagsInterface := d.Get("tags").(map[string]interface{}) for k, v := range tagsInterface { tpl.AddPair(strings.ToUpper(k), v) @@ -389,6 +421,41 @@ func flattenGroupTemplate(d *schema.ResourceData, meta interface{}, groupTpl *dy } + if vectorsInterface, ok := d.GetOk("template_section"); ok { + for _, vectorIf := range vectorsInterface.([]interface{}) { + vector := vectorIf.(map[string]interface{}) + vecName := vector["name"].(string) + vecTags := vector["tags"].(map[string]interface{}) + + // Suppose vector key unicity + vectorTpl, err := groupTpl.GetVector(strings.ToUpper(vecName)) + if err != nil { + continue + } + + tags := make(map[string]interface{}) + for _, pair := range vectorTpl.Pairs { + for k, _ := range vecTags { + if strings.ToUpper(k) != pair.Key() { + continue + } + tags[k] = pair.Value + break + } + } + + err = d.Set("template_section", []interface{}{ + map[string]interface{}{ + "name": vecName, + "tags": tags, + }, + }) + if err != nil { + return err + } + } + } + tags := make(map[string]interface{}) tagsAll := make(map[string]interface{}) @@ -491,6 +558,48 @@ func resourceOpennebulaGroupUpdate(ctx context.Context, d *schema.ResourceData, update = true } + if d.HasChange("template_section") { + oldVectorsIf, newVectorsIf := d.GetChange("template_section") + oldVectors := oldVectorsIf.([]interface{}) + newVectors := newVectorsIf.([]interface{}) + + // Here we suppose vector key unicity + // delete vectors + for _, oldVectorIf := range oldVectors { + oldVector := oldVectorIf.(map[string]interface{}) + oldVectorName := oldVector["name"].(string) + + if len(newVectors) == 0 { + newTpl.Del(strings.ToUpper(oldVectorName)) + } + + // if a new vector has the same name, keep it + for _, newVectorIf := range newVectors { + newVector := newVectorIf.(map[string]interface{}) + + if oldVectorName == newVector["name"].(string) { + continue + } + newTpl.Del(strings.ToUpper(oldVectorName)) + } + + } + + // add/update vectors + for _, newVectorIf := range newVectors { + newVector := newVectorIf.(map[string]interface{}) + newVectorName := strings.ToUpper(newVector["name"].(string)) + + newTpl.Del(strings.ToUpper(newVectorName)) + newVec := newTpl.AddVector(newVectorName) + for k, v := range newVector["tags"].(map[string]interface{}) { + newVec.AddPair(k, v) + } + } + + update = true + } + if d.HasChange("tags") { oldTagsIf, newTagsIf := d.GetChange("tags") diff --git a/website/docs/r/group.html.markdown b/website/docs/r/group.html.markdown index 2886bb52e..bbc63b1a9 100644 --- a/website/docs/r/group.html.markdown +++ b/website/docs/r/group.html.markdown @@ -52,6 +52,14 @@ resource "opennebula_group" "example" { tags = { environment = "example" } + + template_section { + name = "test" + tags = { + tag1 = "value1" + } + } + } ``` @@ -64,6 +72,7 @@ The following arguments are supported: * `quotas` - (Optional) See [Quotas parameters](#quotas-parameters) below for details * `sunstone` - (Optional) Allow users and group admins to access specific views. See [Sunstone parameters](#sunstone-parameters) below for details * `tags` - (Optional) Group tags (Key = value) +* `template_section` - (Optional) Allow to add a custom vector. See [Template section parameters](#template-section-parameters) ### Quotas parameters @@ -108,13 +117,20 @@ The following arguments are supported: * `running_vms` - (Optional) Number of Virtual Machines allowed in `RUNNING` state. Defaults to `default quota`. * `system_disk_size` - (Optional) Maximum disk global size (in MB) allowed on a `SYSTEM` datastore. Defaults to `default quota`. -#### Sunstone parameters +### Sunstone parameters * `default_view` - (Optional) Default Sunstone view for regular users * `views` - (Optional) List of available views for regular users * `group_admin_default_view` - (Optional) Default Sunstone view for group admin users * `group_admin_views` - (Optional) List of available views for the group admins +### Template section parameters + +`template_section` supports the following arguments: + +* `name` - (Optional) The vector name. +* `tags` - (Optional) Collection of custom tags. + ## Attribute Reference The following attribute is exported: