summaryrefslogtreecommitdiff
path: root/robusta_krr/formatters
diff options
context:
space:
mode:
authorПавел Жуков <33721692+LeaveMyYard@users.noreply.github.com>2023-05-26 23:02:47 +0300
committerПавел Жуков <33721692+LeaveMyYard@users.noreply.github.com>2023-05-26 23:02:47 +0300
commited73cfbd95b9222c57950ff727397e251ebca247 (patch)
tree3c0bd4a24db102f73a9843cea5e63ebd0b77e056 /robusta_krr/formatters
parent0609ae5b62947b0d55505dec23b9b4d3a5909d89 (diff)
Refactor Formatters, use functional approach
Diffstat (limited to 'robusta_krr/formatters')
-rw-r--r--robusta_krr/formatters/__init__.py8
-rw-r--r--robusta_krr/formatters/json.py22
-rw-r--r--robusta_krr/formatters/pprint.py22
-rw-r--r--robusta_krr/formatters/table.py171
-rw-r--r--robusta_krr/formatters/yaml.py23
5 files changed, 100 insertions, 146 deletions
diff --git a/robusta_krr/formatters/__init__.py b/robusta_krr/formatters/__init__.py
index 0fc1c80..325cf01 100644
--- a/robusta_krr/formatters/__init__.py
+++ b/robusta_krr/formatters/__init__.py
@@ -1,4 +1,4 @@
-from .json import JSONFormatter
-from .pprint import PPrintFormatter
-from .table import TableFormatter
-from .yaml import YAMLFormatter
+from .json import json
+from .pprint import pprint
+from .table import table
+from .yaml import yaml
diff --git a/robusta_krr/formatters/json.py b/robusta_krr/formatters/json.py
index 2c3a51e..c391da2 100644
--- a/robusta_krr/formatters/json.py
+++ b/robusta_krr/formatters/json.py
@@ -1,21 +1,7 @@
-from __future__ import annotations
-
-from robusta_krr.core.abstract.formatters import BaseFormatter
+from robusta_krr.core.abstract import formatters
from robusta_krr.core.models.result import Result
-class JSONFormatter(BaseFormatter):
- """Formatter for JSON output."""
-
- __display_name__ = "json"
-
- def format(self, result: Result) -> str:
- """Format the result as JSON.
-
- :param result: The results to format.
- :type result: :class:`core.result.Result`
- :returns: The formatted results.
- :rtype: str
- """
-
- return result.json(indent=2)
+@formatters.register()
+def json(result: Result) -> str:
+ return result.json(indent=2)
diff --git a/robusta_krr/formatters/pprint.py b/robusta_krr/formatters/pprint.py
index bdfcc4c..9be637c 100644
--- a/robusta_krr/formatters/pprint.py
+++ b/robusta_krr/formatters/pprint.py
@@ -1,23 +1,9 @@
-from __future__ import annotations
-
from pprint import pformat
-from robusta_krr.core.abstract.formatters import BaseFormatter
+from robusta_krr.core.abstract import formatters
from robusta_krr.core.models.result import Result
-class PPrintFormatter(BaseFormatter):
- """Formatter for object output with python's pprint module."""
-
- __display_name__ = "pprint"
-
- def format(self, result: Result) -> str:
- """Format the result using pprint.pformat(...)
-
- :param result: The results to format.
- :type result: :class:`core.result.Result`
- :returns: The formatted results.
- :rtype: str
- """
-
- return pformat(result.dict())
+@formatters.register()
+def pprint(result: Result) -> str:
+ return pformat(result.dict())
diff --git a/robusta_krr/formatters/table.py b/robusta_krr/formatters/table.py
index 8ef1696..9776d80 100644
--- a/robusta_krr/formatters/table.py
+++ b/robusta_krr/formatters/table.py
@@ -1,10 +1,8 @@
-from __future__ import annotations
-
import itertools
from rich.table import Table
-from robusta_krr.core.abstract.formatters import BaseFormatter
+from robusta_krr.core.abstract import formatters
from robusta_krr.core.models.allocations import RecommendationValue
from robusta_krr.core.models.result import ResourceScan, ResourceType, Result
from robusta_krr.utils import resource_units
@@ -13,88 +11,85 @@ NONE_LITERAL = "unset"
NAN_LITERAL = "?"
-class TableFormatter(BaseFormatter):
- """Formatter for text output."""
-
- __display_name__ = "table"
- __rich_console__ = True
-
- def _format(self, value: RecommendationValue) -> str:
- if value is None:
- return NONE_LITERAL
- elif isinstance(value, str):
- return NAN_LITERAL
- else:
- return resource_units.format(value)
-
- def _format_request_str(self, item: ResourceScan, resource: ResourceType, selector: str) -> str:
- allocated = getattr(item.object.allocations, selector)[resource]
- recommended = getattr(item.recommended, selector)[resource]
- severity = recommended.severity
-
- return (
- f"[{severity.color}]"
- + self._format(allocated)
- + " -> "
- + self._format(recommended.value)
- + f"[/{severity.color}]"
- )
-
- def format(self, result: Result) -> Table:
- """Format the result as text.
-
- :param result: The result to format.
- :type result: :class:`core.result.Result`
- :returns: The formatted results.
- :rtype: str
- """
-
- table = Table(
- show_header=True,
- header_style="bold magenta",
- title=f"\n{result.description}\n" if result.description else None,
- title_justify="left",
- title_style="",
- # TODO: Fix points calculation at [MAIN-270]
- # caption=f"Scan result ({result.score} points)",
- )
-
- table.add_column("Number", justify="right", no_wrap=True)
- table.add_column("Cluster", style="cyan")
- table.add_column("Namespace", style="cyan")
- table.add_column("Name", style="cyan")
- table.add_column("Pods", style="cyan")
- table.add_column("Old Pods", style="cyan")
- table.add_column("Type", style="cyan")
- table.add_column("Container", style="cyan")
- for resource in ResourceType:
- table.add_column(f"{resource.name} Requests")
- table.add_column(f"{resource.name} Limits")
-
- for _, group in itertools.groupby(
- enumerate(result.scans), key=lambda x: (x[1].object.cluster, x[1].object.namespace, x[1].object.name)
- ):
- group_items = list(group)
-
- for j, (i, item) in enumerate(group_items):
- last_row = j == len(group_items) - 1
- full_info_row = j == 0
-
- table.add_row(
- f"[{item.severity.color}]{i + 1}.[/{item.severity.color}]",
- item.object.cluster if full_info_row else "",
- item.object.namespace if full_info_row else "",
- item.object.name if full_info_row else "",
- f"{item.object.current_pods_count}" if full_info_row else "",
- f"{item.object.deleted_pods_count}" if full_info_row else "",
- item.object.kind if full_info_row else "",
- item.object.container,
- *[
- self._format_request_str(item, resource, selector)
- for resource in ResourceType
- for selector in ["requests", "limits"]
- ],
- end_section=last_row,
- )
-
- return table
+def _format(value: RecommendationValue) -> str:
+ if value is None:
+ return NONE_LITERAL
+ elif isinstance(value, str):
+ return NAN_LITERAL
+ else:
+ return resource_units.format(value)
+
+
+def _format_request_str(item: ResourceScan, resource: ResourceType, selector: str) -> str:
+ allocated = getattr(item.object.allocations, selector)[resource]
+ recommended = getattr(item.recommended, selector)[resource]
+ severity = recommended.severity
+
+ return (
+ f"[{severity.color}]"
+ + _format(allocated)
+ + " -> "
+ + _format(recommended.value)
+ + f"[/{severity.color}]"
+ )
+
+
+@formatters.register(rich_console=True)
+def table(result: Result) -> Table:
+ """Format the result as text.
+
+ :param result: The result to format.
+ :type result: :class:`core.result.Result`
+ :returns: The formatted results.
+ :rtype: str
+ """
+
+ table = Table(
+ show_header=True,
+ header_style="bold magenta",
+ title=f"\n{result.description}\n" if result.description else None,
+ title_justify="left",
+ title_style="",
+ # TODO: Fix points calculation at [MAIN-270]
+ # caption=f"Scan result ({result.score} points)",
+ )
+
+ table.add_column("Number", justify="right", no_wrap=True)
+ table.add_column("Cluster", style="cyan")
+ table.add_column("Namespace", style="cyan")
+ table.add_column("Name", style="cyan")
+ table.add_column("Pods", style="cyan")
+ table.add_column("Old Pods", style="cyan")
+ table.add_column("Type", style="cyan")
+ table.add_column("Container", style="cyan")
+ for resource in ResourceType:
+ table.add_column(f"{resource.name} Requests")
+ table.add_column(f"{resource.name} Limits")
+
+ for _, group in itertools.groupby(
+ enumerate(result.scans), key=lambda x: (x[1].object.cluster, x[1].object.namespace, x[1].object.name)
+ ):
+ group_items = list(group)
+
+ for j, (i, item) in enumerate(group_items):
+ last_row = j == len(group_items) - 1
+ full_info_row = j == 0
+
+ table.add_row(
+ f"[{item.severity.color}]{i + 1}.[/{item.severity.color}]",
+ item.object.cluster if full_info_row else "",
+ item.object.namespace if full_info_row else "",
+ item.object.name if full_info_row else "",
+ f"{item.object.current_pods_count}" if full_info_row else "",
+ f"{item.object.deleted_pods_count}" if full_info_row else "",
+ item.object.kind if full_info_row else "",
+ item.object.container,
+ *[
+ _format_request_str(item, resource, selector)
+ for resource in ResourceType
+ for selector in ["requests", "limits"]
+ ],
+ end_section=last_row,
+ )
+
+ return table
diff --git a/robusta_krr/formatters/yaml.py b/robusta_krr/formatters/yaml.py
index c494bc1..37a030c 100644
--- a/robusta_krr/formatters/yaml.py
+++ b/robusta_krr/formatters/yaml.py
@@ -1,24 +1,11 @@
-from __future__ import annotations
-
import json
-import yaml
+import yaml as yaml_module
-from robusta_krr.core.abstract.formatters import BaseFormatter
+from robusta_krr.core.abstract import formatters
from robusta_krr.core.models.result import Result
-class YAMLFormatter(BaseFormatter):
- """Formatter for YAML output."""
-
- __display_name__ = "yaml"
-
- def format(self, result: Result) -> str:
- """Format the result as YAML.
-
- :param result: The results to format.
- :type result: :class:`core.result.Result`
- :returns: The formatted results.
- :rtype: str
- """
- return yaml.dump(json.loads(result.json()), sort_keys=False)
+@formatters.register()
+def yaml(result: Result) -> str:
+ return yaml_module.dump(json.loads(result.json()), sort_keys=False)