4
4
from typing import FrozenSet
5
5
6
6
from kube_downscaler import helper
7
- from pykube import Deployment , StatefulSet
7
+ from pykube import Deployment , StatefulSet , CronJob
8
8
from kube_downscaler .resources .stack import Stack
9
9
10
10
logger = logging .getLogger (__name__ )
@@ -85,7 +85,6 @@ def autoscale_resource(
85
85
resource .name ,
86
86
)
87
87
else :
88
- replicas = resource .replicas
89
88
ignore = False
90
89
91
90
upscale_period = resource .annotations .get (
@@ -128,15 +127,29 @@ def autoscale_resource(
128
127
now , uptime
129
128
) and not helper .matches_time_spec (now , downtime )
130
129
131
- logger .debug (
132
- "%s %s/%s has %s replicas (original: %s, uptime: %s)" ,
133
- resource .kind ,
134
- resource .namespace ,
135
- resource .name ,
136
- replicas ,
137
- original_replicas ,
138
- uptime ,
139
- )
130
+ if resource .kind == "CronJob" :
131
+ suspended = resource .obj ["spec" ]["suspend" ]
132
+ replicas = 0 if suspended else 1
133
+ logger .debug (
134
+ "%s %s/%s is %s (original: %s, uptime: %s)" ,
135
+ resource .kind ,
136
+ resource .namespace ,
137
+ resource .name ,
138
+ "suspended" if suspended else "not suspended" ,
139
+ "suspended" if original_replicas == 0 else "not suspended" ,
140
+ uptime ,
141
+ )
142
+ else :
143
+ replicas = resource .replicas
144
+ logger .debug (
145
+ "%s %s/%s has %s replicas (original: %s, uptime: %s)" ,
146
+ resource .kind ,
147
+ resource .namespace ,
148
+ resource .name ,
149
+ replicas ,
150
+ original_replicas ,
151
+ uptime ,
152
+ )
140
153
update_needed = False
141
154
142
155
if (
@@ -146,17 +159,30 @@ def autoscale_resource(
146
159
and original_replicas
147
160
and int (original_replicas ) > 0
148
161
):
149
- logger .info (
150
- "Scaling up %s %s/%s from %s to %s replicas (uptime: %s, downtime: %s)" ,
151
- resource .kind ,
152
- resource .namespace ,
153
- resource .name ,
154
- replicas ,
155
- original_replicas ,
156
- uptime ,
157
- downtime ,
158
- )
159
- resource .replicas = int (original_replicas )
162
+
163
+ if resource .kind == "CronJob" :
164
+ resource .obj ["spec" ]["suspend" ] = False
165
+ resource .obj ["spec" ]["startingDeadlineSeconds" ] = 0
166
+ logger .info (
167
+ "Unsuspending %s %s/%s (uptime: %s, downtime: %s)" ,
168
+ resource .kind ,
169
+ resource .namespace ,
170
+ resource .name ,
171
+ uptime ,
172
+ downtime ,
173
+ )
174
+ else :
175
+ resource .replicas = int (original_replicas )
176
+ logger .info (
177
+ "Scaling up %s %s/%s from %s to %s replicas (uptime: %s, downtime: %s)" ,
178
+ resource .kind ,
179
+ resource .namespace ,
180
+ resource .name ,
181
+ replicas ,
182
+ original_replicas ,
183
+ uptime ,
184
+ downtime ,
185
+ )
160
186
resource .annotations [ORIGINAL_REPLICAS_ANNOTATION ] = None
161
187
update_needed = True
162
188
elif (
@@ -180,18 +206,29 @@ def autoscale_resource(
180
206
)
181
207
else :
182
208
183
- logger .info (
184
- "Scaling down %s %s/%s from %s to %s replicas (uptime: %s, downtime: %s)" ,
185
- resource .kind ,
186
- resource .namespace ,
187
- resource .name ,
188
- replicas ,
189
- target_replicas ,
190
- uptime ,
191
- downtime ,
192
- )
209
+ if resource .kind == "CronJob" :
210
+ resource .obj ["spec" ]["suspend" ] = True
211
+ logger .info (
212
+ "Suspending %s %s/%s (uptime: %s, downtime: %s)" ,
213
+ resource .kind ,
214
+ resource .namespace ,
215
+ resource .name ,
216
+ uptime ,
217
+ downtime ,
218
+ )
219
+ else :
220
+ resource .replicas = target_replicas
221
+ logger .info (
222
+ "Scaling down %s %s/%s from %s to %s replicas (uptime: %s, downtime: %s)" ,
223
+ resource .kind ,
224
+ resource .namespace ,
225
+ resource .name ,
226
+ replicas ,
227
+ target_replicas ,
228
+ uptime ,
229
+ downtime ,
230
+ )
193
231
resource .annotations [ORIGINAL_REPLICAS_ANNOTATION ] = str (replicas )
194
- resource .replicas = target_replicas
195
232
update_needed = True
196
233
if update_needed :
197
234
if dry_run :
@@ -292,6 +329,7 @@ def scale(
292
329
exclude_namespaces : FrozenSet [str ],
293
330
exclude_deployments : FrozenSet [str ],
294
331
exclude_statefulsets : FrozenSet [str ],
332
+ exclude_cronjobs : FrozenSet [str ],
295
333
dry_run : bool ,
296
334
grace_period : int ,
297
335
downtime_replicas : int ,
@@ -352,3 +390,20 @@ def scale(
352
390
grace_period ,
353
391
downtime_replicas ,
354
392
)
393
+ if "cronjobs" in include_resources :
394
+ autoscale_resources (
395
+ api ,
396
+ CronJob ,
397
+ namespace ,
398
+ exclude_namespaces ,
399
+ exclude_cronjobs ,
400
+ upscale_period ,
401
+ downscale_period ,
402
+ default_uptime ,
403
+ default_downtime ,
404
+ forced_uptime ,
405
+ dry_run ,
406
+ now ,
407
+ grace_period ,
408
+ downtime_replicas ,
409
+ )
0 commit comments