Skip to content
This repository was archived by the owner on Mar 16, 2024. It is now read-only.

Commit e5533b0

Browse files
authored
Merge pull request #1799 from tylerslaton/refactor-resources
Refactor Resources struct and its helper functions
2 parents 9d86922 + 8113ff8 commit e5533b0

File tree

3 files changed

+88
-63
lines changed

3 files changed

+88
-63
lines changed

pkg/apis/internal.admin.acorn.io/v1/resources.go

Lines changed: 75 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ import (
1111
// external controllers to programmatically set the resources easier. Calls to
1212
// its functions are mutating.
1313
type Resources struct {
14+
Unlimited bool `json:"unlimited,omitempty"`
15+
1416
Apps int `json:"apps,omitempty"`
1517
Containers int `json:"containers,omitempty"`
1618
Jobs int `json:"jobs,omitempty"`
1719
Volumes int `json:"volumes,omitempty"`
1820
Secrets int `json:"secrets,omitempty"`
1921
Images int `json:"images,omitempty"`
22+
Projects int `json:"projects,omitempty"`
2023

2124
VolumeStorage resource.Quantity `json:"volumeStorage,omitempty"`
2225
Memory resource.Quantity `json:"memory,omitempty"`
@@ -31,6 +34,7 @@ func (current *Resources) Add(incoming Resources) {
3134
current.Volumes += incoming.Volumes
3235
current.Secrets += incoming.Secrets
3336
current.Images += incoming.Images
37+
current.Projects += incoming.Projects
3438

3539
current.VolumeStorage.Add(incoming.VolumeStorage)
3640
current.Memory.Add(incoming.Memory)
@@ -39,18 +43,28 @@ func (current *Resources) Add(incoming Resources) {
3943

4044
// Remove will remove the resources of another Resources struct from the current one.
4145
func (current *Resources) Remove(incoming Resources, all bool) {
42-
current.Apps -= incoming.Apps
43-
current.Containers -= incoming.Containers
44-
current.Jobs -= incoming.Jobs
45-
current.Volumes -= incoming.Volumes
46-
current.Images -= incoming.Images
46+
// Do not allow resources to go below 0
47+
nonNegativeSubtract := func(currentVal, incomingVal int) int {
48+
difference := currentVal - incomingVal
49+
if difference < 0 {
50+
difference = 0
51+
}
52+
return difference
53+
}
54+
55+
current.Apps = nonNegativeSubtract(current.Apps, incoming.Apps)
56+
current.Containers = nonNegativeSubtract(current.Containers, incoming.Containers)
57+
current.Jobs = nonNegativeSubtract(current.Jobs, incoming.Jobs)
58+
current.Volumes = nonNegativeSubtract(current.Volumes, incoming.Volumes)
59+
current.Images = nonNegativeSubtract(current.Images, incoming.Images)
60+
current.Projects = nonNegativeSubtract(current.Projects, incoming.Projects)
4761

4862
current.Memory.Sub(incoming.Memory)
4963
current.CPU.Sub(incoming.CPU)
5064

5165
// Only remove persistent resources if all is true.
5266
if all {
53-
current.Secrets -= incoming.Secrets
67+
current.Secrets = nonNegativeSubtract(current.Secrets, incoming.Secrets)
5468
current.VolumeStorage.Sub(incoming.VolumeStorage)
5569
}
5670
}
@@ -60,87 +74,86 @@ func (current *Resources) Remove(incoming Resources, all bool) {
6074
// an aggregated error will be returned with all exceeded resources.
6175
func (current *Resources) Fits(incoming Resources) error {
6276
exceededResources := []string{}
63-
if current.Apps < incoming.Apps {
64-
exceededResources = append(exceededResources, "Apps")
65-
}
66-
if current.Containers < incoming.Containers {
67-
exceededResources = append(exceededResources, "Containers")
68-
}
69-
if current.Jobs < incoming.Jobs {
70-
exceededResources = append(exceededResources, "Jobs")
71-
}
72-
if current.Volumes < incoming.Volumes {
73-
exceededResources = append(exceededResources, "Volumes")
74-
}
75-
if current.Secrets < incoming.Secrets {
76-
exceededResources = append(exceededResources, "Secrets")
77-
}
78-
if current.Images < incoming.Images {
79-
exceededResources = append(exceededResources, "Images")
80-
}
8177

82-
if current.VolumeStorage.Cmp(incoming.VolumeStorage) < 0 {
83-
exceededResources = append(exceededResources, "VolumeStorage")
84-
}
85-
if current.Memory.Cmp(incoming.Memory) < 0 {
86-
exceededResources = append(exceededResources, "Memory")
78+
// Define function for checking int resources to keep code DRY
79+
checkResource := func(resource string, currentVal, incomingVal int) {
80+
if currentVal <= incomingVal {
81+
exceededResources = append(exceededResources, resource)
82+
}
8783
}
88-
if current.CPU.Cmp(incoming.CPU) < 0 {
89-
exceededResources = append(exceededResources, "Cpu")
84+
85+
// Define function for checking quantity resources to keep code DRY
86+
checkQuantityResource := func(resource string, currentVal, incomingVal resource.Quantity) {
87+
if currentVal.Cmp(incomingVal) <= 0 {
88+
exceededResources = append(exceededResources, resource)
89+
}
9090
}
9191

92+
checkResource("Apps", current.Apps, incoming.Apps)
93+
checkResource("Containers", current.Containers, incoming.Containers)
94+
checkResource("Jobs", current.Jobs, incoming.Jobs)
95+
checkResource("Volumes", current.Volumes, incoming.Volumes)
96+
checkResource("Secrets", current.Secrets, incoming.Secrets)
97+
checkResource("Images", current.Images, incoming.Images)
98+
checkResource("Projects", current.Projects, incoming.Projects)
99+
100+
checkQuantityResource("VolumeStorage", current.VolumeStorage, incoming.VolumeStorage)
101+
checkQuantityResource("Memory", current.Memory, incoming.Memory)
102+
checkQuantityResource("Cpu", current.CPU, incoming.CPU)
103+
92104
// Build an aggregated error message for the exceeded resources
93105
if len(exceededResources) > 0 {
94-
return fmt.Errorf("exceeded quota for resources: %s", strings.Join(exceededResources, ", "))
106+
return fmt.Errorf("quota would be exceeded for resources: %s", strings.Join(exceededResources, ", "))
95107
}
96108

97109
return nil
98110
}
99111

100-
// ToString will return a string representation of the Resources struct.
101-
func (current *Resources) ToString() string {
102-
resources := []string{}
103-
if current.Apps > 0 {
104-
resources = append(resources, fmt.Sprintf("Apps:%v", current.Apps))
105-
}
106-
if current.Containers > 0 {
107-
resources = append(resources, fmt.Sprintf("Containers:%v", current.Containers))
108-
}
109-
if current.Jobs > 0 {
110-
resources = append(resources, fmt.Sprintf("Jobs:%v", current.Jobs))
111-
}
112-
if current.Volumes > 0 {
113-
resources = append(resources, fmt.Sprintf("Volumes:%v", current.Volumes))
114-
}
115-
if current.Secrets > 0 {
116-
resources = append(resources, fmt.Sprintf("Secrets:%v", current.Secrets))
117-
}
118-
if current.Images > 0 {
119-
resources = append(resources, fmt.Sprintf("Images:%v", current.Images))
120-
}
112+
// NonEmptyString will return a string representation of the non-empty
113+
// Resources within the struct.
114+
func (current *Resources) NonEmptyString() string {
115+
var resources []string
121116

122-
if !current.VolumeStorage.IsZero() {
123-
resources = append(resources, fmt.Sprintf("VolumeStorage:%v", current.VolumeStorage))
124-
}
125-
if !current.Memory.IsZero() {
126-
resources = append(resources, fmt.Sprintf("Memory:%v", current.Memory))
117+
// Define function for checking int resources to keep code DRY
118+
checkResource := func(resource string, value int) {
119+
if value > 0 {
120+
resources = append(resources, resource)
121+
}
127122
}
128-
if !current.CPU.IsZero() {
129-
resources = append(resources, fmt.Sprintf("CPU:%v", current.CPU))
123+
124+
// Define function for checking quantity resources to keep code DRY
125+
checkQuantityResource := func(resource string, currentVal resource.Quantity) {
126+
if !currentVal.IsZero() {
127+
resources = append(resources, resource)
128+
}
130129
}
131130

132-
return strings.Join(resources, ",")
131+
checkResource("Apps", current.Apps)
132+
checkResource("Containers", current.Containers)
133+
checkResource("Jobs", current.Jobs)
134+
checkResource("Volumes", current.Volumes)
135+
checkResource("Secrets", current.Secrets)
136+
checkResource("Images", current.Images)
137+
checkResource("Projects", current.Projects)
138+
139+
checkQuantityResource("VolumeStorage", current.VolumeStorage)
140+
checkQuantityResource("Memory", current.Memory)
141+
checkQuantityResource("Cpu", current.CPU)
142+
143+
return strings.Join(resources, ", ")
133144
}
134145

135146
// Equals will check if the current Resources struct is equal to another. This is useful
136147
// to avoid needing to do a deep equal on the entire struct.
137148
func (current *Resources) Equals(incoming Resources) bool {
138-
return current.Apps == incoming.Apps &&
149+
return current.Unlimited == incoming.Unlimited &&
150+
current.Apps == incoming.Apps &&
139151
current.Containers == incoming.Containers &&
140152
current.Jobs == incoming.Jobs &&
141153
current.Volumes == incoming.Volumes &&
142154
current.Secrets == incoming.Secrets &&
143155
current.Images == incoming.Images &&
156+
current.Projects == incoming.Projects &&
144157
current.VolumeStorage.Cmp(incoming.VolumeStorage) == 0 &&
145158
current.Memory.Cmp(incoming.Memory) == 0 &&
146159
current.CPU.Cmp(incoming.CPU) == 0

pkg/controller/quota/quota.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func WaitForAllocation(req router.Request, resp router.Response) error {
5353
4. Exists and has successfully allocated the resources requested.
5454
*/
5555
if quotaRequest.Status.FailedResources != nil {
56-
status.Error(fmt.Errorf("failed to provision the following resources: %v", quotaRequest.Status.FailedResources.ToString()))
56+
status.Error(fmt.Errorf("failed to provision the following resources: %v", quotaRequest.Status.FailedResources.NonEmptyString()))
5757
} else if cond := quotaRequest.Status.Condition(adminv1.QuotaRequestCondition); cond.Error {
5858
status.Error(fmt.Errorf("error occurred while trying to allocate quota: %v", cond.Message))
5959
} else if err != nil || !quotaRequest.Spec.Resources.Equals(quotaRequest.Status.AllocatedResources) {

pkg/openapi/generated/openapi_generated.go

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)