forked from TrueCloudLab/frostfs-testlib
Add Iptables helper
Signed-off-by: Dmitriy Zayakin <d.zayakin@yadro.com>
This commit is contained in:
parent
02c079eda3
commit
b1c21e0e5b
7 changed files with 288 additions and 3 deletions
|
@ -1,13 +1,16 @@
|
|||
import copy
|
||||
import itertools
|
||||
import time
|
||||
|
||||
import frostfs_testlib.resources.optionals as optionals
|
||||
from frostfs_testlib.reporter import get_reporter
|
||||
from frostfs_testlib.shell import CommandOptions, Shell
|
||||
from frostfs_testlib.steps import epoch
|
||||
from frostfs_testlib.steps.iptables import IpTablesHelper
|
||||
from frostfs_testlib.storage.cluster import Cluster, ClusterNode, StorageNode
|
||||
from frostfs_testlib.storage.controllers.disk_controller import DiskController
|
||||
from frostfs_testlib.testing import parallel
|
||||
from frostfs_testlib.testing.test_control import run_optionally
|
||||
from frostfs_testlib.testing.test_control import run_optionally, wait_for_success
|
||||
from frostfs_testlib.utils.failover_utils import (
|
||||
wait_all_storage_nodes_returned,
|
||||
wait_for_host_offline,
|
||||
|
@ -24,6 +27,7 @@ class ClusterStateController:
|
|||
self.detached_disks: dict[str, DiskController] = {}
|
||||
self.stopped_storage_nodes: list[ClusterNode] = []
|
||||
self.stopped_s3_gates: list[ClusterNode] = []
|
||||
self.dropped_traffic: list[ClusterNode] = []
|
||||
self.cluster = cluster
|
||||
self.shell = shell
|
||||
self.suspended_services: dict[str, list[ClusterNode]] = {}
|
||||
|
@ -191,6 +195,62 @@ class ClusterStateController:
|
|||
[node.host.wait_success_resume_process(process_name) for node in list_nodes]
|
||||
self.suspended_services = {}
|
||||
|
||||
@reporter.step_deco("Drop traffic to {node}, with ports - {ports}, nodes - {block_nodes}")
|
||||
def drop_traffic(
|
||||
self,
|
||||
mode: str,
|
||||
node: ClusterNode,
|
||||
wakeup_timeout: int,
|
||||
ports: list[str] = None,
|
||||
block_nodes: list[ClusterNode] = None,
|
||||
) -> None:
|
||||
allowed_modes = ["ports", "nodes"]
|
||||
assert mode in allowed_modes
|
||||
|
||||
match mode:
|
||||
case "ports":
|
||||
IpTablesHelper.drop_input_traffic_to_port(node, ports)
|
||||
case "nodes":
|
||||
list_ip = self._parse_intefaces(block_nodes)
|
||||
IpTablesHelper.drop_input_traffic_to_node(node, list_ip)
|
||||
time.sleep(wakeup_timeout)
|
||||
self.dropped_traffic.append(node)
|
||||
|
||||
@reporter.step_deco("Ping traffic")
|
||||
def ping_traffic(
|
||||
self,
|
||||
node: ClusterNode,
|
||||
nodes_list: list[ClusterNode],
|
||||
expect_result: int,
|
||||
) -> bool:
|
||||
shell = node.host.get_shell()
|
||||
options = CommandOptions(check=False)
|
||||
ips = self._parse_intefaces(nodes_list)
|
||||
for ip in ips:
|
||||
code = shell.exec(f"ping {ip} -c 1", options).return_code
|
||||
if code != expect_result:
|
||||
return False
|
||||
return True
|
||||
|
||||
@reporter.step_deco("Start traffic to {node}")
|
||||
def restore_traffic(
|
||||
self,
|
||||
mode: str,
|
||||
node: ClusterNode,
|
||||
) -> None:
|
||||
allowed_modes = ["ports", "nodes"]
|
||||
assert mode in allowed_modes
|
||||
|
||||
match mode:
|
||||
case "ports":
|
||||
IpTablesHelper.restore_input_traffic_to_port(node=node)
|
||||
case "nodes":
|
||||
IpTablesHelper.restore_input_traffic_to_node(node=node)
|
||||
|
||||
@reporter.step_deco("Restore blocked nodes")
|
||||
def restore_all_traffic(self):
|
||||
parallel(self._restore_traffic_to_node, self.dropped_traffic)
|
||||
|
||||
@run_optionally(optionals.OPTIONAL_FAILOVER_ENABLED)
|
||||
@reporter.step_deco("Hard reboot host {node} via magic SysRq option")
|
||||
def panic_reboot_host(self, node: ClusterNode, wait_for_return: bool = True):
|
||||
|
@ -217,3 +277,16 @@ class ClusterStateController:
|
|||
disk_controller = DiskController(node, device, mountpoint)
|
||||
|
||||
return disk_controller
|
||||
|
||||
def _restore_traffic_to_node(self, node):
|
||||
IpTablesHelper.restore_input_traffic_to_port(node)
|
||||
IpTablesHelper.restore_input_traffic_to_node(node)
|
||||
|
||||
def _parse_intefaces(self, nodes: list[ClusterNode]):
|
||||
interfaces = []
|
||||
for node in nodes:
|
||||
dict_interfaces = node.host.config.interfaces
|
||||
for type, ip in dict_interfaces.items():
|
||||
if "mgmt" not in type:
|
||||
interfaces.append(ip)
|
||||
return interfaces
|
||||
|
|
|
@ -23,3 +23,21 @@ class StorageObjectInfo(ObjectRef):
|
|||
attributes: Optional[list[dict[str, str]]] = None
|
||||
tombstone: Optional[str] = None
|
||||
locks: Optional[list[LockObjectInfo]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class NodeNetmapInfo:
|
||||
node_id: str
|
||||
node_status: str
|
||||
node_data_ip: str
|
||||
continent: str
|
||||
country: str
|
||||
country_code: str
|
||||
external_address: str
|
||||
location: str
|
||||
node: str
|
||||
price: int
|
||||
sub_div: str
|
||||
sub_div_code: int
|
||||
un_locode: str
|
||||
role: str
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue