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 }