@@ -12,7 +12,7 @@ import (
1212)
1313
1414const (
15- quotaName = "pelican-wings"
15+ quotaName = "pelican-wings"
1616 limitRangeName = "pelican-wings"
1717)
1818
@@ -25,7 +25,10 @@ func (e *Environment) EnsureResourceQuota(ctx context.Context) error {
2525 }
2626
2727 ns := e .namespace ()
28- quota := buildResourceQuota (ns , & cfg .Kubernetes .ResourceQuota )
28+ quota , err := buildResourceQuota (ns , & cfg .Kubernetes .ResourceQuota )
29+ if err != nil {
30+ return err
31+ }
2932
3033 existing , err := e .client .CoreV1 ().ResourceQuotas (ns ).Get (ctx , quotaName , metav1.GetOptions {})
3134 if err == nil {
@@ -56,7 +59,10 @@ func (e *Environment) EnsureLimitRange(ctx context.Context) error {
5659 }
5760
5861 ns := e .namespace ()
59- lr := buildLimitRange (ns , & cfg .Kubernetes .LimitRange )
62+ lr , err := buildLimitRange (ns , & cfg .Kubernetes .LimitRange )
63+ if err != nil {
64+ return err
65+ }
6066
6167 existing , err := e .client .CoreV1 ().LimitRanges (ns ).Get (ctx , limitRangeName , metav1.GetOptions {})
6268 if err == nil {
@@ -78,31 +84,46 @@ func (e *Environment) EnsureLimitRange(ctx context.Context) error {
7884 return nil
7985}
8086
87+ // setQuantity parses a quantity string into the resource list under key when
88+ // the value is non-empty. Unlike resource.MustParse it returns an error for
89+ // invalid (user-configurable) values instead of panicking the process.
90+ func setQuantity (list corev1.ResourceList , key corev1.ResourceName , field , value string ) error {
91+ if value == "" {
92+ return nil
93+ }
94+ q , err := resource .ParseQuantity (value )
95+ if err != nil {
96+ return errors .Wrapf (err , "environment/kubernetes: invalid quantity %q for %s" , value , field )
97+ }
98+ list [key ] = q
99+ return nil
100+ }
101+
81102// buildResourceQuota constructs the ResourceQuota spec from config values.
82- func buildResourceQuota (namespace string , cfg * config.KubeResourceQuota ) * corev1.ResourceQuota {
103+ func buildResourceQuota (namespace string , cfg * config.KubeResourceQuota ) ( * corev1.ResourceQuota , error ) {
83104 hard := corev1.ResourceList {}
84105
85- if cfg .CPULimit != "" {
86- hard [corev1 .ResourceLimitsCPU ] = resource .MustParse (cfg .CPULimit )
87- }
88- if cfg .MemoryLimit != "" {
89- hard [corev1 .ResourceLimitsMemory ] = resource .MustParse (cfg .MemoryLimit )
90- }
91- if cfg .CPURequest != "" {
92- hard [corev1 .ResourceRequestsCPU ] = resource .MustParse (cfg .CPURequest )
93- }
94- if cfg .MemoryRequest != "" {
95- hard [corev1 .ResourceRequestsMemory ] = resource .MustParse (cfg .MemoryRequest )
106+ for _ , q := range []struct {
107+ key corev1.ResourceName
108+ field string
109+ value string
110+ }{
111+ {corev1 .ResourceLimitsCPU , "cpu_limit" , cfg .CPULimit },
112+ {corev1 .ResourceLimitsMemory , "memory_limit" , cfg .MemoryLimit },
113+ {corev1 .ResourceRequestsCPU , "cpu_request" , cfg .CPURequest },
114+ {corev1 .ResourceRequestsMemory , "memory_request" , cfg .MemoryRequest },
115+ {corev1 .ResourceRequestsStorage , "max_storage" , cfg .MaxStorage },
116+ } {
117+ if err := setQuantity (hard , q .key , q .field , q .value ); err != nil {
118+ return nil , err
119+ }
96120 }
97121 if cfg .MaxPods > 0 {
98122 hard [corev1 .ResourcePods ] = * resource .NewQuantity (cfg .MaxPods , resource .DecimalSI )
99123 }
100124 if cfg .MaxPVCs > 0 {
101125 hard [corev1 .ResourcePersistentVolumeClaims ] = * resource .NewQuantity (cfg .MaxPVCs , resource .DecimalSI )
102126 }
103- if cfg .MaxStorage != "" {
104- hard [corev1 .ResourceRequestsStorage ] = resource .MustParse (cfg .MaxStorage )
105- }
106127
107128 return & corev1.ResourceQuota {
108129 ObjectMeta : metav1.ObjectMeta {
@@ -115,35 +136,34 @@ func buildResourceQuota(namespace string, cfg *config.KubeResourceQuota) *corev1
115136 Spec : corev1.ResourceQuotaSpec {
116137 Hard : hard ,
117138 },
118- }
139+ }, nil
119140}
120141
121142// buildLimitRange constructs the LimitRange spec from config values.
122- func buildLimitRange (namespace string , cfg * config.KubeLimitRange ) * corev1.LimitRange {
143+ func buildLimitRange (namespace string , cfg * config.KubeLimitRange ) ( * corev1.LimitRange , error ) {
123144 containerLimit := corev1.LimitRangeItem {
124145 Type : corev1 .LimitTypeContainer ,
125146 Default : corev1.ResourceList {},
126147 DefaultRequest : corev1.ResourceList {},
127148 Max : corev1.ResourceList {},
128149 }
129150
130- if cfg .DefaultCPULimit != "" {
131- containerLimit .Default [corev1 .ResourceCPU ] = resource .MustParse (cfg .DefaultCPULimit )
132- }
133- if cfg .DefaultMemoryLimit != "" {
134- containerLimit .Default [corev1 .ResourceMemory ] = resource .MustParse (cfg .DefaultMemoryLimit )
135- }
136- if cfg .DefaultCPURequest != "" {
137- containerLimit .DefaultRequest [corev1 .ResourceCPU ] = resource .MustParse (cfg .DefaultCPURequest )
138- }
139- if cfg .DefaultMemoryRequest != "" {
140- containerLimit .DefaultRequest [corev1 .ResourceMemory ] = resource .MustParse (cfg .DefaultMemoryRequest )
141- }
142- if cfg .MaxCPU != "" {
143- containerLimit .Max [corev1 .ResourceCPU ] = resource .MustParse (cfg .MaxCPU )
144- }
145- if cfg .MaxMemory != "" {
146- containerLimit .Max [corev1 .ResourceMemory ] = resource .MustParse (cfg .MaxMemory )
151+ for _ , q := range []struct {
152+ list corev1.ResourceList
153+ key corev1.ResourceName
154+ field string
155+ value string
156+ }{
157+ {containerLimit .Default , corev1 .ResourceCPU , "default_cpu_limit" , cfg .DefaultCPULimit },
158+ {containerLimit .Default , corev1 .ResourceMemory , "default_memory_limit" , cfg .DefaultMemoryLimit },
159+ {containerLimit .DefaultRequest , corev1 .ResourceCPU , "default_cpu_request" , cfg .DefaultCPURequest },
160+ {containerLimit .DefaultRequest , corev1 .ResourceMemory , "default_memory_request" , cfg .DefaultMemoryRequest },
161+ {containerLimit .Max , corev1 .ResourceCPU , "max_cpu" , cfg .MaxCPU },
162+ {containerLimit .Max , corev1 .ResourceMemory , "max_memory" , cfg .MaxMemory },
163+ } {
164+ if err := setQuantity (q .list , q .key , q .field , q .value ); err != nil {
165+ return nil , err
166+ }
147167 }
148168
149169 return & corev1.LimitRange {
@@ -157,5 +177,5 @@ func buildLimitRange(namespace string, cfg *config.KubeLimitRange) *corev1.Limit
157177 Spec : corev1.LimitRangeSpec {
158178 Limits : []corev1.LimitRangeItem {containerLimit },
159179 },
160- }
180+ }, nil
161181}
0 commit comments