summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--robusta_krr/core/models/result.py56
-rw-r--r--robusta_krr/core/models/severity.py36
-rw-r--r--robusta_krr/core/models/severity_calculator/__init__.py4
-rw-r--r--robusta_krr/core/models/severity_calculator/base_calculator.py35
-rw-r--r--robusta_krr/core/models/severity_calculator/cpu_calculator.py27
-rw-r--r--robusta_krr/core/models/severity_calculator/default_calculator.py11
-rw-r--r--robusta_krr/core/models/severity_calculator/memory_calculator.py27
7 files changed, 141 insertions, 55 deletions
diff --git a/robusta_krr/core/models/result.py b/robusta_krr/core/models/result.py
index d4e042f..46512bb 100644
--- a/robusta_krr/core/models/result.py
+++ b/robusta_krr/core/models/result.py
@@ -1,6 +1,5 @@
from __future__ import annotations
-import enum
from datetime import datetime
from typing import Any, Optional, Union
@@ -9,60 +8,7 @@ import pydantic as pd
from robusta_krr.core.abstract.formatters import BaseFormatter
from robusta_krr.core.models.allocations import RecommendationValue, ResourceAllocations, ResourceType
from robusta_krr.core.models.objects import K8sObjectData
-
-
-class Severity(str, enum.Enum):
- """The severity of the scan."""
-
- UNKNOWN = "UNKNOWN"
- GOOD = "GOOD"
- OK = "OK"
- WARNING = "WARNING"
- CRITICAL = "CRITICAL"
-
- @property
- def color(self) -> str:
- return {
- self.UNKNOWN: "dim",
- self.GOOD: "green",
- self.OK: "gray",
- self.WARNING: "yellow",
- self.CRITICAL: "red",
- }[self]
-
- @classmethod
- def calculate(
- cls, current: RecommendationValue, recommended: RecommendationValue, resource_type: ResourceType
- ) -> Severity:
- if isinstance(recommended, str) or isinstance(current, str):
- return cls.UNKNOWN
-
- if current is None and recommended is None:
- return cls.GOOD
- if current is None or recommended is None:
- return cls.WARNING
-
- diff = abs(current - recommended)
-
- if resource_type == ResourceType.CPU:
- if diff >= 0.5:
- return cls.CRITICAL
- elif diff >= 0.25:
- return cls.WARNING
- elif diff >= 0.1:
- return cls.OK
- else:
- return cls.GOOD
- else:
- diff_megabytes = diff / 1024 / 1024
- if diff_megabytes >= 500:
- return cls.CRITICAL
- elif diff_megabytes >= 250:
- return cls.WARNING
- elif diff_megabytes >= 100:
- return cls.OK
- else:
- return cls.GOOD
+from robusta_krr.core.models.severity import Severity
class Recommendation(pd.BaseModel):
diff --git a/robusta_krr/core/models/severity.py b/robusta_krr/core/models/severity.py
new file mode 100644
index 0000000..cbe45a2
--- /dev/null
+++ b/robusta_krr/core/models/severity.py
@@ -0,0 +1,36 @@
+from __future__ import annotations
+
+import enum
+
+from robusta_krr.core.models.allocations import RecommendationValue, ResourceType
+
+
+class Severity(str, enum.Enum):
+ """The severity of the scan."""
+
+ UNKNOWN = "UNKNOWN"
+ GOOD = "GOOD"
+ OK = "OK"
+ WARNING = "WARNING"
+ CRITICAL = "CRITICAL"
+
+ @property
+ def color(self) -> str:
+ return {
+ self.UNKNOWN: "dim",
+ self.GOOD: "green",
+ self.OK: "gray",
+ self.WARNING: "yellow",
+ self.CRITICAL: "red",
+ }[self]
+
+ @classmethod
+ def calculate(
+ cls, current: RecommendationValue, recommended: RecommendationValue, resource_type: ResourceType
+ ) -> Severity:
+ from robusta_krr.core.models.severity_calculator import BaseSeverityCalculator
+
+ if isinstance(recommended, str) or isinstance(current, str):
+ return cls.UNKNOWN
+
+ return BaseSeverityCalculator.get_by_resource(resource_type).calculate(current, recommended)
diff --git a/robusta_krr/core/models/severity_calculator/__init__.py b/robusta_krr/core/models/severity_calculator/__init__.py
new file mode 100644
index 0000000..edaafd7
--- /dev/null
+++ b/robusta_krr/core/models/severity_calculator/__init__.py
@@ -0,0 +1,4 @@
+from .base_calculator import BaseSeverityCalculator, bind_calculator
+from .cpu_calculator import CPUSeverityCalculator
+from .default_calculator import DefaultSeverityCalculator
+from .memory_calculator import MemorySeverityCalculator
diff --git a/robusta_krr/core/models/severity_calculator/base_calculator.py b/robusta_krr/core/models/severity_calculator/base_calculator.py
new file mode 100644
index 0000000..832b5a5
--- /dev/null
+++ b/robusta_krr/core/models/severity_calculator/base_calculator.py
@@ -0,0 +1,35 @@
+from __future__ import annotations
+
+import abc
+from typing import Callable, Optional, TypeVar
+
+from robusta_krr.core.models.allocations import ResourceType
+from robusta_krr.core.models.severity import Severity
+
+
+class BaseSeverityCalculator(abc.ABC):
+ # Is here as we are creating this object in get_by_resource method, so it can not have any arguments
+ def __init__(self) -> None:
+ ...
+
+ @abc.abstractmethod
+ def calculate(self, current: Optional[float], recommended: Optional[float]) -> Severity:
+ ...
+
+ @staticmethod
+ def get_by_resource(resource: ResourceType) -> BaseSeverityCalculator:
+ from robusta_krr.core.models.severity_calculator.default_calculator import DefaultSeverityCalculator
+
+ return SEVERITY_CALCULATORS_MAP.get(resource, DefaultSeverityCalculator)()
+
+
+Self = TypeVar("Self", bound=BaseSeverityCalculator)
+SEVERITY_CALCULATORS_MAP: dict[ResourceType, type[BaseSeverityCalculator]] = {}
+
+
+def bind_calculator(resource_type: ResourceType) -> Callable[[type[Self]], type[Self]]:
+ def decorator(cls: type[Self]) -> type[Self]:
+ SEVERITY_CALCULATORS_MAP[resource_type] = cls
+ return cls
+
+ return decorator
diff --git a/robusta_krr/core/models/severity_calculator/cpu_calculator.py b/robusta_krr/core/models/severity_calculator/cpu_calculator.py
new file mode 100644
index 0000000..965adec
--- /dev/null
+++ b/robusta_krr/core/models/severity_calculator/cpu_calculator.py
@@ -0,0 +1,27 @@
+from __future__ import annotations
+
+from typing import Optional
+
+from robusta_krr.core.models.allocations import ResourceType
+from robusta_krr.core.models.severity import Severity
+from robusta_krr.core.models.severity_calculator.base_calculator import BaseSeverityCalculator, bind_calculator
+
+
+@bind_calculator(ResourceType.CPU)
+class CPUSeverityCalculator(BaseSeverityCalculator):
+ def calculate(self, current: Optional[float], recommended: Optional[float]) -> Severity:
+ if current is None and recommended is None:
+ return Severity.GOOD
+ if current is None or recommended is None:
+ return Severity.WARNING
+
+ diff = abs(current - recommended)
+
+ if diff >= 0.5:
+ return Severity.CRITICAL
+ elif diff >= 0.25:
+ return Severity.WARNING
+ elif diff >= 0.1:
+ return Severity.OK
+ else:
+ return Severity.GOOD
diff --git a/robusta_krr/core/models/severity_calculator/default_calculator.py b/robusta_krr/core/models/severity_calculator/default_calculator.py
new file mode 100644
index 0000000..adcb4af
--- /dev/null
+++ b/robusta_krr/core/models/severity_calculator/default_calculator.py
@@ -0,0 +1,11 @@
+from __future__ import annotations
+
+from typing import Optional
+
+from robusta_krr.core.models.severity import Severity
+from robusta_krr.core.models.severity_calculator.base_calculator import BaseSeverityCalculator
+
+
+class DefaultSeverityCalculator(BaseSeverityCalculator):
+ def calculate(self, current: Optional[float], recommended: Optional[float]) -> Severity:
+ return Severity.UNKNOWN
diff --git a/robusta_krr/core/models/severity_calculator/memory_calculator.py b/robusta_krr/core/models/severity_calculator/memory_calculator.py
new file mode 100644
index 0000000..5948949
--- /dev/null
+++ b/robusta_krr/core/models/severity_calculator/memory_calculator.py
@@ -0,0 +1,27 @@
+from __future__ import annotations
+
+from typing import Optional
+
+from robusta_krr.core.models.allocations import ResourceType
+from robusta_krr.core.models.severity import Severity
+from robusta_krr.core.models.severity_calculator.base_calculator import BaseSeverityCalculator, bind_calculator
+
+
+@bind_calculator(ResourceType.Memory)
+class MemorySeverityCalculator(BaseSeverityCalculator):
+ def calculate(self, current: Optional[float], recommended: Optional[float]) -> Severity:
+ if current is None and recommended is None:
+ return Severity.GOOD
+ if current is None or recommended is None:
+ return Severity.WARNING
+
+ diff = abs(current - recommended) / 1024 / 1024
+
+ if diff >= 500:
+ return Severity.CRITICAL
+ elif diff >= 250:
+ return Severity.WARNING
+ elif diff >= 100:
+ return Severity.OK
+ else:
+ return Severity.GOOD