github.com/hashicorp/nomad/api@v0.0.0-20240306165712-3193ac204f65/quota.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package api
     5  
     6  import (
     7  	"fmt"
     8  	"sort"
     9  )
    10  
    11  // Quotas is used to query the quotas endpoints.
    12  type Quotas struct {
    13  	client *Client
    14  }
    15  
    16  // Quotas returns a new handle on the quotas.
    17  func (c *Client) Quotas() *Quotas {
    18  	return &Quotas{client: c}
    19  }
    20  
    21  // List is used to dump all of the quota specs
    22  func (q *Quotas) List(qo *QueryOptions) ([]*QuotaSpec, *QueryMeta, error) {
    23  	var resp []*QuotaSpec
    24  	qm, err := q.client.query("/v1/quotas", &resp, qo)
    25  	if err != nil {
    26  		return nil, nil, err
    27  	}
    28  	sort.Sort(QuotaSpecIndexSort(resp))
    29  	return resp, qm, nil
    30  }
    31  
    32  // PrefixList is used to do a PrefixList search over quota specs
    33  func (q *Quotas) PrefixList(prefix string, qo *QueryOptions) ([]*QuotaSpec, *QueryMeta, error) {
    34  	if qo == nil {
    35  		qo = &QueryOptions{Prefix: prefix}
    36  	} else {
    37  		qo.Prefix = prefix
    38  	}
    39  
    40  	return q.List(qo)
    41  }
    42  
    43  // ListUsage is used to dump all of the quota usages
    44  func (q *Quotas) ListUsage(qo *QueryOptions) ([]*QuotaUsage, *QueryMeta, error) {
    45  	var resp []*QuotaUsage
    46  	qm, err := q.client.query("/v1/quota-usages", &resp, qo)
    47  	if err != nil {
    48  		return nil, nil, err
    49  	}
    50  	sort.Sort(QuotaUsageIndexSort(resp))
    51  	return resp, qm, nil
    52  }
    53  
    54  // PrefixList is used to do a PrefixList search over quota usages
    55  func (q *Quotas) PrefixListUsage(prefix string, qo *QueryOptions) ([]*QuotaUsage, *QueryMeta, error) {
    56  	if qo == nil {
    57  		qo = &QueryOptions{Prefix: prefix}
    58  	} else {
    59  		qo.Prefix = prefix
    60  	}
    61  
    62  	return q.ListUsage(qo)
    63  }
    64  
    65  // Info is used to query a single quota spec by its name.
    66  func (q *Quotas) Info(name string, qo *QueryOptions) (*QuotaSpec, *QueryMeta, error) {
    67  	var resp QuotaSpec
    68  	qm, err := q.client.query("/v1/quota/"+name, &resp, qo)
    69  	if err != nil {
    70  		return nil, nil, err
    71  	}
    72  	return &resp, qm, nil
    73  }
    74  
    75  // Usage is used to query a single quota usage by its name.
    76  func (q *Quotas) Usage(name string, qo *QueryOptions) (*QuotaUsage, *QueryMeta, error) {
    77  	var resp QuotaUsage
    78  	qm, err := q.client.query("/v1/quota/usage/"+name, &resp, qo)
    79  	if err != nil {
    80  		return nil, nil, err
    81  	}
    82  	return &resp, qm, nil
    83  }
    84  
    85  // Register is used to register a quota spec.
    86  func (q *Quotas) Register(spec *QuotaSpec, qo *WriteOptions) (*WriteMeta, error) {
    87  	wm, err := q.client.put("/v1/quota", spec, nil, qo)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  	return wm, nil
    92  }
    93  
    94  // Delete is used to delete a quota spec
    95  func (q *Quotas) Delete(quota string, qo *WriteOptions) (*WriteMeta, error) {
    96  	wm, err := q.client.delete(fmt.Sprintf("/v1/quota/%s", quota), nil, nil, qo)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	return wm, nil
   101  }
   102  
   103  // QuotaSpec specifies the allowed resource usage across regions.
   104  type QuotaSpec struct {
   105  	// Name is the name for the quota object
   106  	Name string
   107  
   108  	// Description is an optional description for the quota object
   109  	Description string
   110  
   111  	// Limits is the set of quota limits encapsulated by this quota object. Each
   112  	// limit applies quota in a particular region and in the future over a
   113  	// particular priority range and datacenter set.
   114  	Limits []*QuotaLimit
   115  
   116  	// Raft indexes to track creation and modification
   117  	CreateIndex uint64
   118  	ModifyIndex uint64
   119  }
   120  
   121  // QuotaLimit describes the resource limit in a particular region.
   122  type QuotaLimit struct {
   123  	// Region is the region in which this limit has affect
   124  	Region string
   125  
   126  	// RegionLimit is the quota limit that applies to any allocation within a
   127  	// referencing namespace in the region. A value of zero is treated as
   128  	// unlimited and a negative value is treated as fully disallowed. This is
   129  	// useful for once we support GPUs
   130  	RegionLimit *Resources
   131  
   132  	// VariablesLimit is the maximum total size of all variables
   133  	// Variable.EncryptedData. A value of zero is treated as unlimited and a
   134  	// negative value is treated as fully disallowed.
   135  	VariablesLimit *int `mapstructure:"variables_limit" hcl:"variables_limit,optional"`
   136  
   137  	// Hash is the hash of the object and is used to make replication efficient.
   138  	Hash []byte
   139  }
   140  
   141  // QuotaUsage is the resource usage of a Quota
   142  type QuotaUsage struct {
   143  	Name        string
   144  	Used        map[string]*QuotaLimit
   145  	CreateIndex uint64
   146  	ModifyIndex uint64
   147  }
   148  
   149  // QuotaSpecIndexSort is a wrapper to sort QuotaSpecs by CreateIndex. We
   150  // reverse the test so that we get the highest index first.
   151  type QuotaSpecIndexSort []*QuotaSpec
   152  
   153  func (q QuotaSpecIndexSort) Len() int {
   154  	return len(q)
   155  }
   156  
   157  func (q QuotaSpecIndexSort) Less(i, j int) bool {
   158  	return q[i].CreateIndex > q[j].CreateIndex
   159  }
   160  
   161  func (q QuotaSpecIndexSort) Swap(i, j int) {
   162  	q[i], q[j] = q[j], q[i]
   163  }
   164  
   165  // QuotaUsageIndexSort is a wrapper to sort QuotaUsages by CreateIndex. We
   166  // reverse the test so that we get the highest index first.
   167  type QuotaUsageIndexSort []*QuotaUsage
   168  
   169  func (q QuotaUsageIndexSort) Len() int {
   170  	return len(q)
   171  }
   172  
   173  func (q QuotaUsageIndexSort) Less(i, j int) bool {
   174  	return q[i].CreateIndex > q[j].CreateIndex
   175  }
   176  
   177  func (q QuotaUsageIndexSort) Swap(i, j int) {
   178  	q[i], q[j] = q[j], q[i]
   179  }
   180  
   181  // QuotaLimitSort is a wrapper to sort QuotaLimits
   182  type QuotaLimitSort []*QuotaLimit
   183  
   184  func (q QuotaLimitSort) Len() int {
   185  	return len(q)
   186  }
   187  
   188  func (q QuotaLimitSort) Less(i, j int) bool {
   189  	return q[i].Region < q[j].Region
   190  }
   191  
   192  func (q QuotaLimitSort) Swap(i, j int) {
   193  	q[i], q[j] = q[j], q[i]
   194  }