mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
cli: quota status extension for devices (#23899)
quota status CLI now displays device limits (if present in the quota spec)
This commit is contained in:
committed by
GitHub
parent
650e783b06
commit
47f3313ffd
@@ -6,6 +6,7 @@ package command
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -123,6 +124,12 @@ func (c *QuotaStatusCommand) Run(args []string) int {
|
||||
c.Ui.Output(c.Colorize().Color("\n[bold]Quota Limits[reset]"))
|
||||
c.Ui.Output(formatQuotaLimits(spec, usages))
|
||||
|
||||
// If quota has limits on devices, format them separately
|
||||
if slices.ContainsFunc(spec.Limits, func(l *api.QuotaLimit) bool { return l.RegionLimit.Devices != nil }) {
|
||||
c.Ui.Output(c.Colorize().Color("\n[bold]Quota Device Limits[reset]"))
|
||||
c.Ui.Output(formatQuotaDevices(spec, usages))
|
||||
}
|
||||
|
||||
// Display any failures
|
||||
if len(failures) != 0 {
|
||||
c.Ui.Error(c.Colorize().Color("\n[bold][red]Lookup Failures[reset]"))
|
||||
@@ -176,6 +183,17 @@ func formatQuotaSpecBasics(spec *api.QuotaSpec) string {
|
||||
return formatKV(basic)
|
||||
}
|
||||
|
||||
// lookupUsage returns the regions quota usage for the limit
|
||||
func lookupUsage(usages map[string]*api.QuotaUsage, specLimit *api.QuotaLimit) (*api.QuotaLimit, bool) {
|
||||
usage, ok := usages[specLimit.Region]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
used, ok := usage.Used[base64.StdEncoding.EncodeToString(specLimit.Hash)]
|
||||
return used, ok
|
||||
}
|
||||
|
||||
// formatQuotaLimits formats the limits to display the quota usage versus the
|
||||
// limit per quota limit. It takes as input the specification as well as quota
|
||||
// usage by region. The formatter handles missing usages.
|
||||
@@ -193,24 +211,12 @@ func formatQuotaLimits(spec *api.QuotaSpec, usages map[string]*api.QuotaUsage) s
|
||||
for _, specLimit := range spec.Limits {
|
||||
i++
|
||||
|
||||
// lookupUsage returns the regions quota usage for the limit
|
||||
lookupUsage := func() (*api.QuotaLimit, bool) {
|
||||
usage, ok := usages[specLimit.Region]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
used, ok := usage.Used[base64.StdEncoding.EncodeToString(specLimit.Hash)]
|
||||
return used, ok
|
||||
}
|
||||
|
||||
used, ok := lookupUsage()
|
||||
used, ok := lookupUsage(usages, specLimit)
|
||||
if !ok {
|
||||
cores := fmt.Sprintf("- / %s", formatQuotaLimitInt(specLimit.RegionLimit.Cores))
|
||||
cpu := fmt.Sprintf("- / %s", formatQuotaLimitInt(specLimit.RegionLimit.CPU))
|
||||
memory := fmt.Sprintf("- / %s", formatQuotaLimitInt(specLimit.RegionLimit.MemoryMB))
|
||||
memoryMax := fmt.Sprintf("- / %s", formatQuotaLimitInt(specLimit.RegionLimit.MemoryMaxMB))
|
||||
|
||||
vars := fmt.Sprintf("- / %s", formatQuotaLimitInt(specLimit.VariablesLimit))
|
||||
limits[i] = fmt.Sprintf("%s|%s|%s|%s|%s|%s", specLimit.Region, cpu, cores, memory, memoryMax, vars)
|
||||
continue
|
||||
@@ -252,6 +258,34 @@ func formatQuotaLimitInt(value *int) string {
|
||||
return strconv.Itoa(v)
|
||||
}
|
||||
|
||||
func formatQuotaDevices(spec *api.QuotaSpec, usages map[string]*api.QuotaUsage) string {
|
||||
devices := []string{"Region|Device Name|Device Usage"}
|
||||
i := 0
|
||||
|
||||
for _, specLimit := range spec.Limits {
|
||||
i++
|
||||
|
||||
usage := "-"
|
||||
used, ok := lookupUsage(usages, specLimit)
|
||||
if !ok {
|
||||
for _, d := range specLimit.RegionLimit.Devices {
|
||||
devices = append(devices, fmt.Sprintf("%s|%s|%s / %d", specLimit.Region, d.Name, usage, *d.Count))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
for _, d := range specLimit.RegionLimit.Devices {
|
||||
idx := slices.IndexFunc(used.RegionLimit.Devices, func(dd *api.RequestedDevice) bool { return dd.Name == d.Name })
|
||||
if idx >= 0 {
|
||||
usage = fmt.Sprintf("%d", int(*used.RegionLimit.Devices[idx].Count))
|
||||
}
|
||||
|
||||
devices = append(devices, fmt.Sprintf("%s|%s|%s / %d", specLimit.Region, d.Name, usage, *d.Count))
|
||||
}
|
||||
}
|
||||
return formatList(devices)
|
||||
}
|
||||
|
||||
func getQuotaByPrefix(client *api.Quotas, quota string) (match *api.QuotaSpec, possible []*api.QuotaSpec, err error) {
|
||||
// Do a prefix lookup
|
||||
quotas, _, err := client.PrefixList(quota, nil)
|
||||
|
||||
Reference in New Issue
Block a user