@@ -11,12 +11,15 @@ import (
1111// external controllers to programmatically set the resources easier. Calls to
1212// its functions are mutating.
1313type 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.
4145func (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.
6175func (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.
137148func (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
0 commit comments