Merge "Add "ceph osd pool ls detail" cmd keywords"

This commit is contained in:
Zuul 2025-05-08 20:10:18 +00:00 committed by Gerrit Code Review
commit 7c2cadae45
6 changed files with 314 additions and 0 deletions

View File

@ -0,0 +1,86 @@
import time
from framework.ssh.ssh_connection import SSHConnection
from keywords.base_keyword import BaseKeyword
from keywords.ceph.object.ceph_osd_pool_ls_detail_object import CephOsdPoolLsDetailObject
from keywords.ceph.object.ceph_osd_pool_ls_detail_output import CephOsdPoolLsDetailOutput
class CephOsdPoolLsDetailKeywords(BaseKeyword):
"""
Class for ceph osd pool ls detail keywords
"""
def __init__(self, ssh_connection: SSHConnection):
"""
Constructor
Args:
ssh_connection (SSHConnection): SSHConnection
"""
self.ssh_connection = ssh_connection
def get_ceph_osd_pool_ls_detail_list(self) -> list[CephOsdPoolLsDetailObject]:
"""
Gets the "ceph osd pool ls detail" command as a list of `CephOsdPoolLsDetailObject` objects.
Args: None
Returns: list of 'CephOsdPoolLsDetailObject' objects.
"""
output = self.ssh_connection.send("ceph osd pool ls detail")
self.validate_success_return_code(self.ssh_connection)
ceph_osd_pool_ls_detail_objects = CephOsdPoolLsDetailOutput(output).get_ceph_osd_pool_list()
return ceph_osd_pool_ls_detail_objects
def wait_for_ceph_osd_pool_replicated_size_update(self, pool_name: str, expected_replicated_size: int, timeout: int = 600) -> bool:
"""
Waits timeout amount of time for "ceph osd pool ls detail" replicated size update
Args:
pool_name (str): the pool name
expected_replicated_size (int): the expected replicated size value
timeout (int): amount of timeout
Returns:
bool: True if the pool replicated size is updated as expected
"""
output = self.ssh_connection.send("ceph osd pool ls detail")
pool_object = CephOsdPoolLsDetailOutput(output).get_ceph_osd_pool(pool_name)
replicated_update_timeout = time.time() + timeout
while time.time() < replicated_update_timeout:
ceph_osd_pool_replication_size = pool_object.get_replicated_size()
if ceph_osd_pool_replication_size == expected_replicated_size:
return True
time.sleep(10)
raise ValueError(f"replicated value is {ceph_osd_pool_replication_size}, not as expected value {expected_replicated_size}")
def wait_for_ceph_osd_pool_min_size_update(self, pool_name: str, expected_min_size: int, timeout: int = 600) -> bool:
"""
Waits timeout amount of time for "ceph osd pool ls detail" min_size update
Args:
pool_name (str): the pool name
expected_min_size (int): the expected replicated size value
timeout (int): amount of timeout
Returns:
bool: True if the pool min_size is updated as expected
"""
output = self.ssh_connection.send("ceph osd pool ls detail")
pool_object = CephOsdPoolLsDetailOutput(output).get_ceph_osd_pool(pool_name)
mini_update_timeout = time.time() + timeout
while time.time() < mini_update_timeout:
ceph_osd_pool_min_size = pool_object.get_min_size()
if ceph_osd_pool_min_size == expected_min_size:
return True
time.sleep(10)
raise ValueError(f"replicated value is {ceph_osd_pool_min_size}, not as expected value {expected_min_size}")

View File

@ -0,0 +1,65 @@
class CephOsdPoolLsDetailTableParser:
"""
Class for "ceph osd pool ls detail" table parsing.
The "ceph osd pool ls detail" table is a string formatted as a table, resulting from the execution of the command
'ceph osd pool ls detail' in a Linux terminal.
This class receives a "ceph osd pool ls detail" table, as shown below, in its constructor and returns a list of dictionaries.
Each of these dictionaries has the following keys:
1) pool_id;
2) pool_name;
3) replicated_size;
4) min_size;
could create more if needed
An example of a "ceph osd pool ls detail" table:
pool 1 '.mgr' replicated size 2 min_size 1 crush_rule 9 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode
on last_change 119 lfor 0/0/28 flags hashpspool stripe_width 0 application mgr read_balance_score 1.25
pool 2 'kube-cephfs-metadata' replicated size 2 min_size 1 crush_rule 11 object_hash rjenkins pg_num 16 pgp_num 16
autoscale_mode on last_change 122 lfor 0/0/28 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16
recovery_priority 5 application cephfs read_balance_score 1.56
pool 3 'kube-rbd' replicated size 2 min_size 1 crush_rule 10 object_hash rjenkins pg_num 32 pgp_num 32
autoscale_mode on last_change 121 lfor 0/0/30 flags hashpspool,selfmanaged_snaps stripe_width 0 application rbd
read_balance_score 1.25
pool 4 'kube-cephfs-data' replicated size 2 min_size 1 crush_rule 12 object_hash rjenkins pg_num 32 pgp_num 32
autoscale_mode on last_change 123 lfor 0/0/30 flags hashpspool stripe_width 0 application cephfs
read_balance_score 2.03
'\n'
Note: 1) The table has no headers. We can learn about the headers through the names of the dictionary keys.
2) there is '\n' at the end of the table
"""
def __init__(self, command_output):
self.command_output = command_output
def get_output_values_list(self):
"""
Getter for output values list.
Returns: the output values list as a list of dictionaries with the following keys:
1) pool_id;
2) pool_name;
3) replicated_size;
4) min_size;
"""
if not self.command_output:
return []
# remove '\n' from output
cleaned_list = [item for item in self.command_output if item != "\n"]
output_values = []
for line in cleaned_list:
values = line.split()
list_item = {
"pool_id": int(values[1].strip()),
"pool_name": values[2].strip().replace("'", ""),
"replicated_size": int(values[5].strip()),
"min_size": int(values[7].strip()),
}
output_values.append(list_item)
return output_values

View File

@ -0,0 +1,64 @@
class CephOsdPoolLsDetailObject:
"""
Class to handle the data provided by the 'ceph osd pool ls detail' command execution.
This command generates the
output table shown below, where each object of this class represents a single row in that table.
'ceph osd pool ls detail'
pool 1 '.mgr' replicated size 2 min_size 1 crush_rule 9 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on
last_change 119 lfor 0/0/28 flags hashpspool stripe_width 0 application mgr read_balance_score 1.25
pool 2 'kube-cephfs-metadata' replicated size 2 min_size 1 crush_rule 11 object_hash rjenkins pg_num 16 pgp_num 16
autoscale_mode on last_change 122 lfor 0/0/28 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16
recovery_priority 5 application cephfs read_balance_score 1.56
pool 3 'kube-rbd' replicated size 2 min_size 1 crush_rule 10 object_hash rjenkins pg_num 32 pgp_num 32
autoscale_mode on last_change 121 lfor 0/0/30 flags hashpspool,selfmanaged_snaps stripe_width 0 application rbd
read_balance_score 1.25
pool 4 'kube-cephfs-data' replicated size 2 min_size 1 crush_rule 12 object_hash rjenkins pg_num 32 pgp_num 32
autoscale_mode on last_change 123 lfor 0/0/30 flags hashpspool stripe_width 0 application cephfs
read_balance_score 2.03
'\n'
"""
def __init__(self):
self.pool_id = -1
self.pool_name = None
self.replicated_size = -1
self.min_size = -1
def get_pool_id(self) -> int:
"""
Getter for pool id like: 1; 2; 3 etc.
Returns: pool int
"""
return self.pool_id
def get_pool_name(self) -> str:
"""
Getter for pool name like: ".mgr"; "kube-cephfs-metadata"; "kube-rbd"; "kube-cephfs-data"
Returns: pool name
"""
return self.pool_name
def get_replicated_size(self) -> int:
"""
Getter for replicated size
Returns: replicated size
"""
return self.replicated_size
def get_min_size(self) -> int:
"""
Getter for min_size
Returns: min_size
"""
return self.min_size

View File

@ -0,0 +1,77 @@
from keywords.ceph.ceph_osd_pool_ls_detail_table_parser import CephOsdPoolLsDetailTableParser
from keywords.ceph.object.ceph_osd_pool_ls_detail_object import CephOsdPoolLsDetailObject
class CephOsdPoolLsDetailOutput:
"""
This class parses the output of the command 'ceph osd pool la detail'
The parsing result is a 'CephOsdPoolLsDetailObject' instance.
Example:
'ceph osd pool ls detail'
pool 1 '.mgr' replicated size 2 min_size 1 crush_rule 9 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode
on last_change 119 lfor 0/0/28 flags hashpspool stripe_width 0 application mgr read_balance_score 1.25
pool 2 'kube-cephfs-metadata' replicated size 2 min_size 1 crush_rule 11 object_hash rjenkins pg_num 16 pgp_num
16 autoscale_mode on last_change 122 lfor 0/0/28 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min
16 recovery_priority 5 application cephfs read_balance_score 1.56
pool 3 'kube-rbd' replicated size 2 min_size 1 crush_rule 10 object_hash rjenkins pg_num 32 pgp_num 32
autoscale_mode on last_change 121 lfor 0/0/30 flags hashpspool,selfmanaged_snaps stripe_width 0 application rbd
read_balance_score 1.25
pool 4 'kube-cephfs-data' replicated size 2 min_size 1 crush_rule 12 object_hash rjenkins pg_num 32 pgp_num 32
autoscale_mode on last_change 123 lfor 0/0/30 flags hashpspool stripe_width 0 application cephfs
read_balance_score 2.03
'\n'
"""
def __init__(self, ceph_osd_pool_ls_detail_output: list[str]):
"""
Constructor
This constructor receives a list of strings, resulting from the execution of the command
ceph osd pool ls detail, and generates a list of CephOsdPoolLsDetailObject objects.
Args:
ceph_osd_pool_ls_detail_output (list[str]): list of strings resulting from the execution of the command `ceph osd pool ls detail`.
"""
ceph_osd_pool_table_parser = CephOsdPoolLsDetailTableParser(ceph_osd_pool_ls_detail_output)
output_values = ceph_osd_pool_table_parser.get_output_values_list()
self.ceph_osd_pool_ls_detail_objects: list[CephOsdPoolLsDetailObject] = []
for item_list in output_values:
ceph_osd_pool_ls_detail_object = CephOsdPoolLsDetailObject()
ceph_osd_pool_ls_detail_object.pool_id = item_list["pool_id"]
ceph_osd_pool_ls_detail_object.pool_name = item_list["pool_name"]
ceph_osd_pool_ls_detail_object.replicated_size = item_list["replicated_size"]
ceph_osd_pool_ls_detail_object.min_size = item_list["min_size"]
self.ceph_osd_pool_ls_detail_objects.append(ceph_osd_pool_ls_detail_object)
def get_ceph_osd_pool_list(self):
"""
Gets the list of `CephOsdPoolLsDetailObject` objects.
Args: none.
Returns (list): The list of `CephOsdPoolLsDetailObject` objects.
"""
return self.ceph_osd_pool_ls_detail_objects
def get_ceph_osd_pool(self, pool_name: str) -> CephOsdPoolLsDetailObject:
"""
This function will get the pool with the name specified from this get_ceph_osd_pool_list.
Args:
pool_name (str): The name of the pool of interest.
Returns:
CephOsdPoolLsDetailObject: The pool object with the name specified.
Raises:
ValueError: If the pool with the specified name does not exist in the output.
"""
for pool_object in self.ceph_osd_pool_ls_detail_objects:
if pool_object.get_pool_name() == pool_name:
return pool_object
else:
raise ValueError(f"There is no pool with the name {pool_name}.")

View File

View File

@ -0,0 +1,22 @@
from keywords.ceph.object.ceph_osd_pool_ls_detail_output import CephOsdPoolLsDetailOutput
ceph_osd_pool_ls_detail_cmd_output = ["pool 1 '.mgr' replicated size 2 min_size 1 crush_rule 9 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 119 lfor 0/0/28 flags hashpspool stripe_width 0 application mgr read_balance_score 1.25", "pool 2 'kube-cephfs-metadata' replicated size 2 min_size 1 crush_rule 11 object_hash rjenkins pg_num 16 pgp_num 16 autoscale_mode on last_change 122 lfor 0/0/28 flags hashpspool stripe_width 0 pg_autoscale_bias 4 pg_num_min 16 recovery_priority 5 application cephfs read_balance_score 1.56", "pool 3 'kube-rbd' replicated size 2 min_size 1 crush_rule 10 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 121 lfor 0/0/30 flags hashpspool,selfmanaged_snaps stripe_width 0 application rbd read_balance_score 1.25", "pool 4 'kube-cephfs-data' replicated size 2 min_size 1 crush_rule 12 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 123 lfor 0/0/30 flags hashpspool stripe_width 0 application cephfs read_balance_score 2.03", "\n"]
def test_ceph_osd_pool_ls_detail_output_parser():
"""
Tests the "ceph osd pool ls detail" parser with a well formated input table.
In this case, the parser must
be able to correctly generate a list of dictionaries.
"""
ceph_osd_pool_ls_detail_output = CephOsdPoolLsDetailOutput(ceph_osd_pool_ls_detail_cmd_output)
ceph_osd_pool_objects = ceph_osd_pool_ls_detail_output.get_ceph_osd_pool_list()
assert len(ceph_osd_pool_objects), 4
mgr_object = ceph_osd_pool_ls_detail_output.get_ceph_osd_pool(".mgr")
assert mgr_object.get_pool_id() == 1
assert mgr_object.get_pool_name() == ".mgr"
assert mgr_object.get_replicated_size() == 2
assert mgr_object.get_min_size() == 1