Skip to content

Commit

Permalink
Merge pull request #81 from samuel-esp/upscale-target-only
Browse files Browse the repository at this point in the history
New Argument: Upscale Target Only
  • Loading branch information
samuel-esp committed Aug 5, 2024
2 parents fe33715 + 84ed31a commit 2e38c9c
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 3 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,17 @@ annotation `downscaler/uptime` on each deployment
configured via environment variable `DEFAULT_DOWNTIME` or via the
annotation `downscaler/downtime` on each deployment
`--upscale-target-only`
: When this optional argument is used, only the namespaces currently
targeted by the downscaler will be upscaled during wake-up times.
For instance, if your downscaler initially manages namespaces
A, B, and C, but is later reconfigured to target only namespaces
B and C, namespace A will remain downscaled if it was downscaled
at the time of reconfiguration. If the parameter is not used,
all previously downscaled namespaces may be upscaled, even if
they are no longer targeted by the downscaler.
`--exclude-namespaces`
: Exclude namespaces from downscaling (list of regex patterns,
Expand Down
5 changes: 5 additions & 0 deletions kube_downscaler/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ def get_parser():
parser.add_argument(
"--interval", type=int, help="Loop interval (default: 30s)", default=30
)
parser.add_argument(
"--upscale-target-only",
help="Upscale only resource in target when waking up namespaces",
action="store_true"
)
parser.add_argument(
"--namespace",
help="Namespace",
Expand Down
4 changes: 4 additions & 0 deletions kube_downscaler/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def main(args=None):
args.exclude_deployments,
args.grace_period,
args.interval,
args.upscale_target_only,
args.dry_run,
args.downtime_replicas,
args.deployment_time_annotation,
Expand All @@ -61,6 +62,7 @@ def run_loop(
exclude_deployments,
grace_period,
interval,
upscale_target_only,
dry_run,
downtime_replicas,
deployment_time_annotation=None,
Expand All @@ -75,6 +77,7 @@ def run_loop(

if len(namespaces) >= 1:
constrained_downscaler = True
logging.info("Namespace argument is not empty, the downscaler will run in constrained mode")
else:
constrained_downscaler = False

Expand All @@ -86,6 +89,7 @@ def run_loop(
downscale_period,
default_uptime,
default_downtime,
upscale_target_only,
include_resources=frozenset(include_resources.split(",")),
exclude_namespaces=frozenset(
re.compile(pattern) for pattern in exclude_namespaces.split(",")
Expand Down
21 changes: 20 additions & 1 deletion kube_downscaler/scaler.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ def parse_time(timestamp: str) -> datetime.datetime:
f"time data '{timestamp}' does not match any format ({', '.join(TIMESTAMP_FORMATS)})"
)


# If the argument --upscale-target-only is present, resources from namespaces not in target won't be processed.
# Otherwise all resources from all namespaces will be processed for scaling if the have original_replicas annotation
def define_scope(exclude, original_replicas, upscale_target_only):
if upscale_target_only:
exclude_condition = exclude
else:
exclude_condition = exclude and not original_replicas

return exclude_condition


def is_grace_period_annotation_integer(value):
try:
int(value) # Attempt to convert the string to an integer
Expand Down Expand Up @@ -834,6 +846,7 @@ def autoscale_resource(
default_downtime: str,
forced_uptime: bool,
forced_downtime: bool,
upscale_target_only: bool,
dry_run: bool,
now: datetime.datetime,
grace_period: int = 0,
Expand All @@ -858,7 +871,9 @@ def autoscale_resource(
if downtime_replicas_from_annotation is not None:
downtime_replicas = downtime_replicas_from_annotation

if exclude:
exclude_condition = define_scope(exclude, original_replicas, upscale_target_only)

if exclude_condition:
logger.debug(
f"{resource.kind} {resource.namespace}/{resource.name} was excluded"
)
Expand Down Expand Up @@ -973,6 +988,7 @@ def autoscale_resources(
default_uptime: str,
default_downtime: str,
forced_uptime: bool,
upscale_target_only: bool,
constrained_downscaler: bool,
dry_run: bool,
now: datetime.datetime,
Expand Down Expand Up @@ -1080,6 +1096,7 @@ def autoscale_resources(
default_downtime_for_namespace,
forced_uptime_for_namespace,
forced_downtime_for_namespace,
upscale_target_only,
dry_run,
now,
grace_period,
Expand Down Expand Up @@ -1308,6 +1325,7 @@ def scale(
downscale_period: str,
default_uptime: str,
default_downtime: str,
upscale_target_only: bool,
include_resources: FrozenSet[str],
exclude_namespaces: FrozenSet[Pattern],
exclude_deployments: FrozenSet[str],
Expand Down Expand Up @@ -1341,6 +1359,7 @@ def scale(
default_uptime,
default_downtime,
forced_uptime,
upscale_target_only,
constrained_downscaler,
dry_run,
now,
Expand Down
Loading

0 comments on commit 2e38c9c

Please sign in to comment.