Skip to content

Commit

Permalink
Handling low max disk size edge-case better, improving human-readable…
Browse files Browse the repository at this point in the history
… output (#4)
  • Loading branch information
AndrewFarley committed Oct 25, 2022
1 parent e689cb0 commit bea6ec4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
31 changes: 28 additions & 3 deletions helpers.py
Expand Up @@ -88,9 +88,9 @@ def exit_gracefully(self, *args):
#############################
# Simple header printing before the program starts, prints the variables this is configured for at runtime
def printHeaderAndConfiguration():
print("---------------------------------------------------------------")
print("-------------------------------------------------------------------------------------------------------------")
print(" Volume Autoscaler - Configuration ")
print("---------------------------------------------------------------")
print("-------------------------------------------------------------------------------------------------------------")
print(" Prometheus URL: {}".format(PROMETHEUS_URL))
print(" Prometheus Version: {}{}".format(PROMETHEUS_VERSION," (upgrade to >= 2.30.0 to prevent some false positives)" if version.parse(PROMETHEUS_VERSION) < version.parse("2.30.0") else ""))
print(" Prometheus Labels: {{{}}}".format(PROMETHEUS_LABEL_MATCH))
Expand All @@ -105,7 +105,7 @@ def printHeaderAndConfiguration():
print(" Verbose Mode: is {}".format("ENABLED" if VERBOSE else "Disabled"))
print(" Dry Run: is {}".format("ENABLED, no scaling will occur!" if DRY_RUN else "Disabled"))
print(" HTTP Timeouts for k8s/prom: is {} seconds".format(HTTP_TIMEOUT))
print("---------------------------------------------------------------")
print("-------------------------------------------------------------------------------------------------------------")


# Figure out how many bytes to scale to based on the original size, scale up percent, minimum increment and maximum size
Expand Down Expand Up @@ -137,6 +137,14 @@ def calculateBytesToScaleTo(original_size, scale_up_percent, min_increment, max_
print(e)
return False

# Check if is integer or float
def is_integer_or_float(n):
try:
float(n)
except ValueError:
return False
else:
return float(n).is_integer()

# Convert the K8s storage size definitions (eg: 10G, 5Ti, etc) into number of bytes
def convert_storage_to_bytes(storage):
Expand Down Expand Up @@ -205,6 +213,9 @@ def convert_bytes_to_storage(bytes):

# Todo: Add Petabytes/Exobytes?

# Ensure its an intger
bytes = int(bytes)

# First, we'll try all base10 values...
# Check if we can convert this into terrabytes
result = try_numeric_format(bytes, 1000000000000, 'T')
Expand Down Expand Up @@ -444,3 +455,17 @@ def send_kubernetes_event(namespace, name, reason, message, type="Normal"):
print("Exception when calling CoreV1Api->create_namespaced_event: %s\n" % e)
except:
traceback.print_exc()

# Print a sexy human readable dict for volume
def print_human_readable_volume_dict(input_dict):
for key in input_dict:
print(" {}: {}".format(key.rjust(24), input_dict[key]), end='')
if key in ['volume_size_spec','volume_size_spec_bytes','volume_size_status','volume_size_status_bytes','scale_up_min_increment','scale_up_max_increment','scale_up_max_size'] and is_integer_or_float(input_dict[key]):
print(" ({})".format(convert_bytes_to_storage(input_dict[key])), end='')
if key in ['scale_cooldown_time']:
print(" ({})".format(time.strftime('%H:%M:%S', time.gmtime(input_dict[key]))), end='')
if key in ['last_resized_at']:
print(" ({})".format(time.strftime('%Y-%m-%d %H:%M:%S %Z %z', time.localtime(input_dict[key]))), end='')
if key in ['scale_up_percent','scale_above_percent']:
print("%", end='')
print("") # Newline
26 changes: 22 additions & 4 deletions main.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
import os
import time
from helpers import INTERVAL_TIME, PROMETHEUS_URL, DRY_RUN, VERBOSE, get_settings_for_prometheus_metrics
from helpers import INTERVAL_TIME, PROMETHEUS_URL, DRY_RUN, VERBOSE, get_settings_for_prometheus_metrics, is_integer_or_float, print_human_readable_volume_dict
from helpers import convert_bytes_to_storage, scale_up_pvc, testIfPrometheusIsAccessible, describe_all_pvcs, send_kubernetes_event
from helpers import fetch_pvcs_from_prometheus, printHeaderAndConfiguration, calculateBytesToScaleTo, GracefulKiller
from prometheus_client import start_http_server, Summary, Gauge, Counter, Info
Expand Down Expand Up @@ -97,8 +97,9 @@
if VERBOSE:
print("Volume {} is {}% in-use of the {} available".format(volume_description,volume_used_percent,pvcs_in_kubernetes[volume_description]['volume_size_status']))
print(" VERBOSE DETAILS:")
for key in pvcs_in_kubernetes[volume_description]:
print(" {}: {}".format(key, pvcs_in_kubernetes[volume_description][key]))
print("-------------------------------------------------------------------------------------------------------------")
print_human_readable_volume_dict(pvcs_in_kubernetes[volume_description])
print("-------------------------------------------------------------------------------------------------------------")

# Check if we are NOT in an alert condition
if volume_used_percent < pvcs_in_kubernetes[volume_description]['scale_above_percent']:
Expand Down Expand Up @@ -152,8 +153,25 @@

# If our resize bytes failed for some reason, eg putting invalid data into the annotations on the PV
if resize_to_bytes == False:
print(" Error/Exception while trying to determine what to resize to, values causing failure:")
print("-------------------------------------------------------------------------------------------------------------")
print(" Error/Exception while trying to determine what to resize to, volume causing failure:")
print("-------------------------------------------------------------------------------------------------------------")
print(pvcs_in_kubernetes[volume_description])
print("-------------------------------------------------------------------------------------------------------------")
continue

# If our resize bytes is less than our original size (because the user set the max-bytes to something too low)
if resize_to_bytes < pvcs_in_kubernetes[volume_description]['volume_size_status_bytes']:
print("-------------------------------------------------------------------------------------------------------------")
print(" Error/Exception while trying to scale this up. Is it possible your maximum SCALE_UP_MAX_SIZE is too small?")
print("-------------------------------------------------------------------------------------------------------------")
print(" Maximum Size: {} ({})".format(pvcs_in_kubernetes[volume_description]['scale_up_max_size'], convert_bytes_to_storage(pvcs_in_kubernetes[volume_description]['scale_up_max_size'])))
print(" Original Size: {} ({})".format(pvcs_in_kubernetes[volume_description]['volume_size_status_bytes'], convert_bytes_to_storage(pvcs_in_kubernetes[volume_description]['volume_size_status_bytes'])))
print(" Resize To: {} ({})".format(resize_to_bytes, convert_bytes_to_storage(resize_to_bytes)))
print("-------------------------------------------------------------------------------------------------------------")
print(" Volume causing failure:")
print_human_readable_volume_dict(pvcs_in_kubernetes[volume_description])
print("-------------------------------------------------------------------------------------------------------------")
continue

# Check if we are already at the max volume size (either globally, or this-volume specific)
Expand Down

0 comments on commit bea6ec4

Please sign in to comment.