Update netmap parser and status check message #195
3 changed files with 26 additions and 24 deletions
|
@ -1,7 +1,7 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from frostfs_testlib.storage.cluster import ClusterNode
|
from frostfs_testlib.storage.cluster import ClusterNode
|
||||||
from frostfs_testlib.storage.dataclasses.storage_object_info import NodeNetInfo, NodeNetmapInfo
|
from frostfs_testlib.storage.dataclasses.storage_object_info import NodeNetInfo, NodeNetmapInfo, NodeStatus
|
||||||
|
|
||||||
|
|
||||||
class NetmapParser:
|
class NetmapParser:
|
||||||
|
@ -44,7 +44,7 @@ class NetmapParser:
|
||||||
regexes = {
|
regexes = {
|
||||||
"node_id": r"\d+: (?P<node_id>\w+)",
|
"node_id": r"\d+: (?P<node_id>\w+)",
|
||||||
"node_data_ips": r"(?P<node_data_ips>/ip4/.+?)$",
|
"node_data_ips": r"(?P<node_data_ips>/ip4/.+?)$",
|
||||||
"node_status": r"(?P<node_status>ONLINE|OFFLINE)",
|
"node_status": r"(?P<node_status>ONLINE|MAINTENANCE|OFFLINE)",
|
||||||
"cluster_name": r"ClusterName: (?P<cluster_name>\w+)",
|
"cluster_name": r"ClusterName: (?P<cluster_name>\w+)",
|
||||||
"continent": r"Continent: (?P<continent>\w+)",
|
"continent": r"Continent: (?P<continent>\w+)",
|
||||||
"country": r"Country: (?P<country>\w+)",
|
"country": r"Country: (?P<country>\w+)",
|
||||||
|
@ -62,14 +62,17 @@ class NetmapParser:
|
||||||
for node in netmap_nodes:
|
for node in netmap_nodes:
|
||||||
for key, regex in regexes.items():
|
for key, regex in regexes.items():
|
||||||
search_result = re.search(regex, node, flags=re.MULTILINE)
|
search_result = re.search(regex, node, flags=re.MULTILINE)
|
||||||
|
if search_result == None:
|
||||||
|
result_netmap[key] = None
|
||||||
|
continue
|
||||||
if key == "node_data_ips":
|
if key == "node_data_ips":
|
||||||
result_netmap[key] = search_result[key].strip().split(" ")
|
result_netmap[key] = search_result[key].strip().split(" ")
|
||||||
continue
|
continue
|
||||||
if key == "external_address":
|
if key == "external_address":
|
||||||
result_netmap[key] = search_result[key].strip().split(",")
|
result_netmap[key] = search_result[key].strip().split(",")
|
||||||
continue
|
continue
|
||||||
if search_result == None:
|
if key == "node_status":
|
||||||
result_netmap[key] = None
|
result_netmap[key] = NodeStatus(search_result[key].strip().lower())
|
||||||
continue
|
continue
|
||||||
result_netmap[key] = search_result[key].strip()
|
result_netmap[key] = search_result[key].strip()
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from frostfs_testlib.steps.network import IpHelper
|
||||||
from frostfs_testlib.storage.cluster import Cluster, ClusterNode, S3Gate, StorageNode
|
from frostfs_testlib.storage.cluster import Cluster, ClusterNode, S3Gate, StorageNode
|
||||||
from frostfs_testlib.storage.controllers.disk_controller import DiskController
|
from frostfs_testlib.storage.controllers.disk_controller import DiskController
|
||||||
from frostfs_testlib.storage.dataclasses.node_base import NodeBase, ServiceClass
|
from frostfs_testlib.storage.dataclasses.node_base import NodeBase, ServiceClass
|
||||||
|
from frostfs_testlib.storage.dataclasses.storage_object_info import NodeStatus
|
||||||
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||||
from frostfs_testlib.testing import parallel
|
from frostfs_testlib.testing import parallel
|
||||||
from frostfs_testlib.testing.test_control import retry, run_optionally, wait_for_success
|
from frostfs_testlib.testing.test_control import retry, run_optionally, wait_for_success
|
||||||
|
@ -413,41 +414,39 @@ class ClusterStateController:
|
||||||
)
|
)
|
||||||
frostfs_adm.morph.set_config(set_key_value=f"MaintenanceModeAllowed={status}")
|
frostfs_adm.morph.set_config(set_key_value=f"MaintenanceModeAllowed={status}")
|
||||||
|
|
||||||
@reporter.step("Set mode node to {status}")
|
@reporter.step("Set node status to {status} in CSC")
|
||||||
def set_mode_node(self, cluster_node: ClusterNode, wallet: WalletInfo, status: str, await_tick: bool = True) -> None:
|
def set_node_status(self, cluster_node: ClusterNode, wallet: WalletInfo, status: NodeStatus, await_tick: bool = True) -> None:
|
||||||
rpc_endpoint = cluster_node.storage_node.get_rpc_endpoint()
|
rpc_endpoint = cluster_node.storage_node.get_rpc_endpoint()
|
||||||
control_endpoint = cluster_node.service(StorageNode).get_control_endpoint()
|
control_endpoint = cluster_node.service(StorageNode).get_control_endpoint()
|
||||||
|
|
||||||
frostfs_adm, frostfs_cli, frostfs_cli_remote = self._get_cli(local_shell=self.shell, local_wallet=wallet, cluster_node=cluster_node)
|
frostfs_adm, frostfs_cli, frostfs_cli_remote = self._get_cli(self.shell, wallet, cluster_node)
|
||||||
node_netinfo = NetmapParser.netinfo(frostfs_cli.netmap.netinfo(rpc_endpoint=rpc_endpoint).stdout)
|
node_netinfo = NetmapParser.netinfo(frostfs_cli.netmap.netinfo(rpc_endpoint).stdout)
|
||||||
|
|
||||||
with reporter.step("If status maintenance, then check that the option is enabled"):
|
if node_netinfo.maintenance_mode_allowed == "false":
|
||||||
if node_netinfo.maintenance_mode_allowed == "false":
|
with reporter.step("Enable maintenance mode"):
|
||||||
frostfs_adm.morph.set_config(set_key_value="MaintenanceModeAllowed=true")
|
frostfs_adm.morph.set_config("MaintenanceModeAllowed=true")
|
||||||
|
|
||||||
with reporter.step(f"Change the status to {status}"):
|
with reporter.step(f"Set node status to {status} using FrostfsCli"):
|
||||||
frostfs_cli_remote.control.set_status(endpoint=control_endpoint, status=status)
|
frostfs_cli_remote.control.set_status(control_endpoint, status.value)
|
||||||
|
|
||||||
if not await_tick:
|
if not await_tick:
|
||||||
return
|
return
|
||||||
|
|
||||||
with reporter.step("Tick 1 epoch, and await 2 block"):
|
with reporter.step("Tick 1 epoch and await 2 block"):
|
||||||
frostfs_adm.morph.force_new_epoch()
|
frostfs_adm.morph.force_new_epoch()
|
||||||
time.sleep(parse_time(MORPH_BLOCK_TIME) * 2)
|
time.sleep(parse_time(MORPH_BLOCK_TIME) * 2)
|
||||||
|
|
||||||
self.check_node_status(status=status, wallet=wallet, cluster_node=cluster_node)
|
self.await_node_status(status, wallet, cluster_node)
|
||||||
|
|
||||||
@wait_for_success(80, 8, title="Wait for storage status become {status}")
|
@wait_for_success(80, 8, title="Wait for node status become {status}")
|
||||||
def check_node_status(self, status: str, wallet: WalletInfo, cluster_node: ClusterNode):
|
def await_node_status(self, status: NodeStatus, wallet: WalletInfo, cluster_node: ClusterNode):
|
||||||
frostfs_cli = FrostfsCli(self.shell, FROSTFS_CLI_EXEC, wallet.config_path)
|
frostfs_cli = FrostfsCli(self.shell, FROSTFS_CLI_EXEC, wallet.config_path)
|
||||||
netmap = NetmapParser.snapshot_all_nodes(
|
netmap = NetmapParser.snapshot_all_nodes(frostfs_cli.netmap.snapshot(cluster_node.storage_node.get_rpc_endpoint()).stdout)
|
||||||
frostfs_cli.netmap.snapshot(rpc_endpoint=cluster_node.storage_node.get_rpc_endpoint()).stdout
|
|
||||||
)
|
|
||||||
netmap = [node for node in netmap if cluster_node.host_ip == node.node]
|
netmap = [node for node in netmap if cluster_node.host_ip == node.node]
|
||||||
if status == "offline":
|
if status == NodeStatus.OFFLINE:
|
||||||
assert cluster_node.host_ip not in netmap, f"{cluster_node.host_ip} not in Offline"
|
assert cluster_node.host_ip not in netmap, f"{cluster_node.host_ip} not in Offline"
|
||||||
else:
|
else:
|
||||||
assert netmap[0].node_status == status.upper(), f"Node state - {netmap[0].node_status} != {status} expect"
|
assert netmap[0].node_status == status, f"Node status should be '{status}', but was '{netmap[0].node_status}'"
|
||||||
|
|
||||||
def _get_cli(
|
def _get_cli(
|
||||||
self, local_shell: Shell, local_wallet: WalletInfo, cluster_node: ClusterNode
|
self, local_shell: Shell, local_wallet: WalletInfo, cluster_node: ClusterNode
|
||||||
|
|
|
@ -28,7 +28,7 @@ class StorageObjectInfo(ObjectRef):
|
||||||
locks: Optional[list[LockObjectInfo]] = None
|
locks: Optional[list[LockObjectInfo]] = None
|
||||||
|
|
||||||
|
|
||||||
class ModeNode(HumanReadableEnum):
|
class NodeStatus(HumanReadableEnum):
|
||||||
MAINTENANCE: str = "maintenance"
|
MAINTENANCE: str = "maintenance"
|
||||||
ONLINE: str = "online"
|
ONLINE: str = "online"
|
||||||
OFFLINE: str = "offline"
|
OFFLINE: str = "offline"
|
||||||
|
@ -37,7 +37,7 @@ class ModeNode(HumanReadableEnum):
|
||||||
@dataclass
|
@dataclass
|
||||||
class NodeNetmapInfo:
|
class NodeNetmapInfo:
|
||||||
node_id: str = None
|
node_id: str = None
|
||||||
node_status: ModeNode = None
|
node_status: NodeStatus = None
|
||||||
node_data_ips: list[str] = None
|
node_data_ips: list[str] = None
|
||||||
cluster_name: str = None
|
cluster_name: str = None
|
||||||
continent: str = None
|
continent: str = None
|
||||||
|
|
Loading…
Reference in a new issue