summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorПавел Жуков <33721692+LeaveMyYard@users.noreply.github.com>2023-05-15 18:19:57 +0300
committerПавел Жуков <33721692+LeaveMyYard@users.noreply.github.com>2023-05-15 18:19:57 +0300
commitfabf1b4fd2c1ae0245d2f0c6000ff8d9d197a29e (patch)
treedb049b2dc9c9149962bdf49ab5f9b23a824bf4e1
parent7bd0c5298e233248e17e6c0cf9ac0e6d7e30ca73 (diff)
[MAIN-169] Add strategy description
-rw-r--r--robusta_krr/core/abstract/strategies.py6
-rw-r--r--robusta_krr/core/models/result.py1
-rw-r--r--robusta_krr/core/runner.py3
-rw-r--r--robusta_krr/formatters/table.py2
-rw-r--r--robusta_krr/strategies/simple.py23
5 files changed, 32 insertions, 3 deletions
diff --git a/robusta_krr/core/abstract/strategies.py b/robusta_krr/core/abstract/strategies.py
index c175bd6..66d93fa 100644
--- a/robusta_krr/core/abstract/strategies.py
+++ b/robusta_krr/core/abstract/strategies.py
@@ -21,7 +21,7 @@ class ResourceRecommendation(pd.BaseModel):
@classmethod
def undefined(cls: type[Self]) -> Self:
- return cls(request=Decimal('NaN'), limit=Decimal('NaN'))
+ return cls(request=float('NaN'), limit=float('NaN'))
class StrategySettings(pd.BaseModel):
@@ -61,6 +61,10 @@ class BaseStrategy(abc.ABC, Generic[_StrategySettings]):
def __str__(self) -> str:
return self.__display_name__.title()
+ @property
+ def description(self) -> str | None:
+ return None
+
@abc.abstractmethod
def run(self, history_data: HistoryData, object_data: K8sObjectData) -> RunResult:
"""Run the strategy to calculate the recommendation"""
diff --git a/robusta_krr/core/models/result.py b/robusta_krr/core/models/result.py
index 7c686f7..e932fef 100644
--- a/robusta_krr/core/models/result.py
+++ b/robusta_krr/core/models/result.py
@@ -93,6 +93,7 @@ class Result(pd.BaseModel):
scans: list[ResourceScan]
score: int = 0
resources: list[str] = ["cpu", "memory"]
+ description: str | None = None
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
diff --git a/robusta_krr/core/runner.py b/robusta_krr/core/runner.py
index 1c67a29..9e1096b 100644
--- a/robusta_krr/core/runner.py
+++ b/robusta_krr/core/runner.py
@@ -144,7 +144,8 @@ class Runner(Configurable):
return Result(
scans=[
ResourceScan.calculate(obj, recommended) for obj, recommended in zip(objects, resource_recommendations)
- ]
+ ],
+ description=self._strategy.description,
)
async def run(self) -> None:
diff --git a/robusta_krr/formatters/table.py b/robusta_krr/formatters/table.py
index 8a93f04..6918512 100644
--- a/robusta_krr/formatters/table.py
+++ b/robusta_krr/formatters/table.py
@@ -50,7 +50,7 @@ class TableFormatter(BaseFormatter):
:rtype: str
"""
- table = Table(show_header=True, header_style="bold magenta", title=f"Scan result ({result.score} points)")
+ table = Table(show_header=True, header_style="bold magenta", title=f"Scan result ({result.score} points)", caption=result.description)
table.add_column("Number", justify="right", no_wrap=True)
table.add_column("Cluster", style="cyan")
diff --git a/robusta_krr/strategies/simple.py b/robusta_krr/strategies/simple.py
index aaf31d7..f528ba8 100644
--- a/robusta_krr/strategies/simple.py
+++ b/robusta_krr/strategies/simple.py
@@ -1,6 +1,7 @@
import pydantic as pd
import numpy as np
from numpy.typing import NDArray
+from textwrap import dedent
from robusta_krr.core.abstract.strategies import (
BaseStrategy,
@@ -41,8 +42,30 @@ class SimpleStrategySettings(StrategySettings):
class SimpleStrategy(BaseStrategy[SimpleStrategySettings]):
+ """
+ A simple strategy that uses the {cpu_percentile} percentile for CPU and
+ the peak memory usage plus {memory_buffer_percentage}% buffer for memory.
+ (Exact numbers can be setup in the settings)
+
+ For CPU, we set a request at the {cpu_percentile} percentile with no limit.
+ Meaning, in {cpu_percentile}% of the cases, your CPU request will be sufficient.
+ For the remaining - we set no limit.
+
+ This means your pod can burst and use any CPU available on the node - e.g.
+ CPU that other pods requested but aren't using right now.
+
+ For memory, we take the maximum value over the past week and add a {memory_buffer_percentage}% buffer.
+ """
+
__display_name__ = "simple"
+ @property
+ def description(self) -> str | None:
+ if self.__doc__ is None:
+ return None
+
+ return dedent(self.__doc__.format_map(self.settings.dict())).strip()
+
def run(self, history_data: HistoryData, object_data: K8sObjectData) -> RunResult:
cpu_usage = self.settings.calculate_cpu_proposal(history_data[ResourceType.CPU])
memory_usage = self.settings.calculate_memory_proposal(history_data[ResourceType.Memory])