Skip to content

Commit

Permalink
F #447 #448: force quotas splitting
Browse files Browse the repository at this point in the history
  • Loading branch information
treywelsh authored and frousselet committed Jul 12, 2023
1 parent cfc0627 commit 8a8d47a
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 101 deletions.
112 changes: 76 additions & 36 deletions opennebula/quotas.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,22 @@ const (
NetFlag = 2
VMFlag = 4
ImgFlag = 8

DatastoreQuota = "datastore"
NetworkQuota = "network"
ImageQuota = "image"
VMQuota = "vm"
)

var validQuotaTypes = []string{DatastoreQuota, NetworkQuota, ImageQuota, VMQuota}

func quotasMapSchema() map[string]*schema.Schema {
return map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Optional: false,
Computed: true,
},
"datastore": {
Type: schema.TypeList,
Optional: true,
Expand All @@ -45,6 +57,7 @@ func quotasMapSchema() map[string]*schema.Schema {
},
},
},
ConflictsWith: []string{"network", "image", "vm"},
},
"network": {
Type: schema.TypeList,
Expand All @@ -65,6 +78,7 @@ func quotasMapSchema() map[string]*schema.Schema {
},
},
},
ConflictsWith: []string{"datastore", "image", "vm"},
},
"image": {
Type: schema.TypeList,
Expand All @@ -85,6 +99,7 @@ func quotasMapSchema() map[string]*schema.Schema {
},
},
},
ConflictsWith: []string{"datastore", "network", "vm"},
},
"vm": {
Type: schema.TypeList,
Expand Down Expand Up @@ -136,12 +151,15 @@ func quotasMapSchema() map[string]*schema.Schema {
},
},
},
ConflictsWith: []string{"datastore", "network", "image"},
},
}
}

func generateQuotas(d *schema.ResourceData, forceDefault bool) (string, error) {

// TODO: check if type match section

tpl := dyn.NewTemplate()

datastore := d.Get("datastore").([]interface{})
Expand Down Expand Up @@ -222,80 +240,102 @@ func generateQuotas(d *schema.ResourceData, forceDefault bool) (string, error) {
return tplStr, nil
}

func flattenQuotasMapFromStructs(d *schema.ResourceData, quotas *shared.QuotasList) error {
func flattenDatastoreQuota(d *schema.ResourceData, quotas []shared.DatastoreQuota) error {
var datastoreQuotas []map[string]interface{}
var imageQuotas []map[string]interface{}
var vmQuotas []map[string]interface{}
var networkQuotas []map[string]interface{}
var q uint8
q = 0

// Get datastore quotas
for _, qds := range quotas.Datastore {
for _, qds := range quotas {
ds := make(map[string]interface{})
ds["id"] = qds.ID
ds["images"] = qds.Images
ds["size"] = qds.Size
if len(ds) > 0 {
datastoreQuotas = append(datastoreQuotas, ds)
}
q = q | DSFlag
}
return d.Set("datastore", datastoreQuotas)
}

func flattenNetworkQuota(d *schema.ResourceData, quotas []shared.NetworkQuota) error {
var networkQuotas []map[string]interface{}

// Get network quotas
for _, qn := range quotas.Network {
for _, qn := range quotas {
n := make(map[string]interface{})
n["id"] = qn.ID
n["leases"] = qn.Leases
if len(n) > 0 {
networkQuotas = append(networkQuotas, n)
}
q = q | NetFlag
}
return d.Set("network", networkQuotas)
}

func flattenVMQuota(d *schema.ResourceData, quotas *shared.VMQuota) error {
var vmQuotas []map[string]interface{}

// Get VM quotas
if quotas.VM != nil {
if quotas != nil {
vm := make(map[string]interface{})

vm["cpu"] = quotas.VM.CPU
vm["memory"] = quotas.VM.Memory
vm["running_cpu"] = quotas.VM.RunningCPU
vm["running_memory"] = quotas.VM.RunningMemory
vm["vms"] = quotas.VM.VMs
vm["running_vms"] = quotas.VM.RunningVMs
vm["system_disk_size"] = quotas.VM.SystemDiskSize
vm["cpu"] = quotas.CPU
vm["memory"] = quotas.Memory
vm["running_cpu"] = quotas.RunningCPU
vm["running_memory"] = quotas.RunningMemory
vm["vms"] = quotas.VMs
vm["running_vms"] = quotas.RunningVMs
vm["system_disk_size"] = quotas.SystemDiskSize

if len(vm) > 0 {
vmQuotas = append(vmQuotas, vm)
}
q = q | VMFlag
}
return d.Set("vm", vmQuotas)
}

func flattenImageQuota(d *schema.ResourceData, quotas []shared.ImageQuota) error {
var imageQuotas []map[string]interface{}

// Get Image quotas
for _, qimg := range quotas.Image {
for _, qimg := range quotas {
img := make(map[string]interface{})
img["id"] = qimg.ID
img["running_vms"] = qimg.RVMs
if len(img) > 0 {
imageQuotas = append(imageQuotas, img)
}
q = q | ImgFlag
}
return d.Set("image", imageQuotas)
}

func flattenQuotasMapFromStructs(d *schema.ResourceData, quotas *shared.QuotasList) error {

for q > 0 {
switch {
case q&DSFlag > 0:
d.Set("datastore", datastoreQuotas)
q = q ^ DSFlag
case q&NetFlag > 0:
d.Set("network", networkQuotas)
q = q ^ NetFlag
case q&VMFlag > 0:
d.Set("vm", vmQuotas)
q = q ^ VMFlag
case q&ImgFlag > 0:
d.Set("image", imageQuotas)
q = q ^ ImgFlag
// quotas resources defines only one kind of resource at a time
log.Printf("[INFO] === type: %s\n", d.Get("type").(string))

// what if type is not defined ?
quotasType := d.Get("type").(string)
if len(quotasType) == 0 {
if len(d.Get("datastore").([]interface{})) > 0 {
quotasType = DatastoreQuota
} else if len(d.Get("network").([]interface{})) > 0 {
quotasType = NetworkQuota
} else if len(d.Get("image").([]interface{})) > 0 {
quotasType = ImageQuota
} else if len(d.Get("vm").([]interface{})) > 0 {
quotasType = VMQuota
}
}

switch quotasType {
case DatastoreQuota:
flattenDatastoreQuota(d, quotas.Datastore)
case NetworkQuota:
flattenNetworkQuota(d, quotas.Network)
case ImageQuota:
flattenImageQuota(d, quotas.Image)
case VMQuota:
flattenVMQuota(d, quotas.VM)
}

return nil
}
56 changes: 34 additions & 22 deletions opennebula/resource_opennebula_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,13 @@ func TestAccGroup(t *testing.T) {
"elements.testkey1": "testvalue1",
"elements.testkey2": "testvalue2",
}),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "datastore.#", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "datastore.0.id", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "datastore.0.images", "3"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "datastore.0.size", "100"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "image.#", "0"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "network.#", "0"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "vm.#", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "vm.0.cpu", "4"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "vm.0.memory", "8192"),
resource.TestCheckResourceAttr("opennebula_group_quotas.datastore", "datastore.#", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.datastore", "datastore.0.id", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.datastore", "datastore.0.images", "3"),
resource.TestCheckResourceAttr("opennebula_group_quotas.datastore", "datastore.0.size", "100"),
resource.TestCheckResourceAttr("opennebula_group_quotas.vm", "vm.#", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.vm", "vm.0.cpu", "4"),
resource.TestCheckResourceAttr("opennebula_group_quotas.vm", "vm.0.memory", "8192"),
),
},
{
Expand All @@ -73,15 +71,13 @@ func TestAccGroup(t *testing.T) {
"elements.testkey2": "testvalue2",
"elements.testkey3": "testvalue3",
}),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "datastore.#", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "datastore.0.id", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "datastore.0.images", "4"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "datastore.0.size", "100"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "image.#", "0"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "network.#", "0"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "vm.#", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "vm.0.cpu", "4"),
resource.TestCheckResourceAttr("opennebula_group_quotas.quotas", "vm.0.memory", "8192"),
resource.TestCheckResourceAttr("opennebula_group_quotas.datastore", "datastore.#", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.datastore", "datastore.0.id", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.datastore", "datastore.0.images", "4"),
resource.TestCheckResourceAttr("opennebula_group_quotas.datastore", "datastore.0.size", "100"),
resource.TestCheckResourceAttr("opennebula_group_quotas.vm", "vm.#", "1"),
resource.TestCheckResourceAttr("opennebula_group_quotas.vm", "vm.0.cpu", "4"),
resource.TestCheckResourceAttr("opennebula_group_quotas.vm", "vm.0.memory", "8192"),
),
},
{
Expand Down Expand Up @@ -222,13 +218,17 @@ resource "opennebula_group" "group" {
}
}
resource "opennebula_group_quotas" "quotas" {
resource "opennebula_group_quotas" "datastore" {
group_id = opennebula_group.group.id
datastore {
id = 1
images = 3
size = 100
}
}
resource "opennebula_group_quotas" "vm" {
group_id = opennebula_group.group.id
vm {
cpu = 4
memory = 8192
Expand Down Expand Up @@ -269,13 +269,17 @@ resource "opennebula_group" "group" {
}
}
resource "opennebula_group_quotas" "quotas" {
resource "opennebula_group_quotas" "datastore" {
group_id = opennebula_group.group.id
datastore {
id = 1
images = 4
size = 100
}
}
resource "opennebula_group_quotas" "vm" {
group_id = opennebula_group.group.id
vm {
cpu = 4
memory = 8192
Expand Down Expand Up @@ -313,13 +317,17 @@ resource "opennebula_group" "group" {
}
}
resource "opennebula_group_quotas" "quotas" {
resource "opennebula_group_quotas" "datastore" {
group_id = opennebula_group.group.id
datastore {
id = 1
images = 4
size = 100
}
}
resource "opennebula_group_quotas" "vm" {
group_id = opennebula_group.group.id
vm {
cpu = 4
memory = 8192
Expand Down Expand Up @@ -373,13 +381,17 @@ resource "opennebula_group" "group" {
}
}
resource "opennebula_group_quotas" "quotas" {
resource "opennebula_group_quotas" "datastore" {
group_id = opennebula_group.group.id
datastore {
id = 1
images = 4
size = 100
}
}
resource "opennebula_group_quotas" "vm" {
group_id = opennebula_group.group.id
vm {
cpu = 4
memory = 8192
Expand Down
29 changes: 28 additions & 1 deletion opennebula/resource_opennebula_user_quotas.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"log"
"strconv"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand All @@ -17,7 +18,7 @@ func resourceOpennebulaUserQuotas() *schema.Resource {
UpdateContext: resourceOpennebulaUserQuotasUpdate,
DeleteContext: resourceOpennebulaUserQuotasDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: resourceOpennebulaUserQuotasImportState,
},
Schema: mergeSchemas(map[string]*schema.Schema{
"user_id": {
Expand Down Expand Up @@ -192,3 +193,29 @@ func resourceOpennebulaUserQuotasDelete(ctx context.Context, d *schema.ResourceD

return nil
}

func resourceOpennebulaUserQuotasImportState(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
fullID := d.Id()
parts := strings.Split(fullID, ":")

if len(parts) < 2 {
return nil, fmt.Errorf("Invalid ID format. Expected: user_id:quotas_section")
}

userID, err := strconv.ParseInt(parts[0], 10, 0)
if err != nil {
return nil, fmt.Errorf("Failed to parse user ID: %s", err)
}

d.SetId(fmt.Sprint(userID))
d.Set("user_id", userID)

quotaType := parts[1]
d.Set("type", quotaType)

if inArray(quotaType, validQuotaTypes) < 0 {
return nil, fmt.Errorf("Invalid quota type %q must be one of: %s", quotaType, strings.Join(validQuotaTypes, ","))
}

return []*schema.ResourceData{d}, nil
}
Loading

0 comments on commit 8a8d47a

Please sign in to comment.