From b6b1644fd66d284aeedb0b8fd6a786c597b0a3c3 Mon Sep 17 00:00:00 2001 From: Vladimir Domnich Date: Fri, 12 Aug 2022 18:44:36 +0300 Subject: [PATCH] Refactor privileges for ssh commands Remove logic that checks for root login and prepends command with sudo, because we should not use root login at all and all commands (that require higher permissions should be prefixed with sudo anyways). Add sudo prefix to privileged commands that require it. Signed-off-by: Vladimir Domnich --- pytest_tests/helpers/iptables_helper.py | 4 ++-- pytest_tests/helpers/sbercloud_helper.py | 7 +++++++ pytest_tests/helpers/service_helper.py | 19 ++++++++++--------- pytest_tests/helpers/ssh_helper.py | 6 +----- .../failovers/test_failover_network.py | 4 ++-- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/pytest_tests/helpers/iptables_helper.py b/pytest_tests/helpers/iptables_helper.py index 3fb4c2b..551a636 100644 --- a/pytest_tests/helpers/iptables_helper.py +++ b/pytest_tests/helpers/iptables_helper.py @@ -6,11 +6,11 @@ class IpTablesHelper: @staticmethod def drop_input_traffic_to_port(client: HostClient, ports: list[str]): for port in ports: - cmd_output = client.exec(cmd=f'iptables -A INPUT -p tcp --dport {port} -j DROP') + cmd_output = client.exec(cmd=f'sudo iptables -A INPUT -p tcp --dport {port} -j DROP') assert cmd_output.rc == 0 @staticmethod def restore_input_traffic_to_port(client: HostClient, ports: list[str]): for port in ports: - cmd_output = client.exec(cmd=f'iptables -D INPUT -p tcp --dport {port} -j DROP') + cmd_output = client.exec(cmd=f'sudo iptables -D INPUT -p tcp --dport {port} -j DROP') assert cmd_output.rc == 0 diff --git a/pytest_tests/helpers/sbercloud_helper.py b/pytest_tests/helpers/sbercloud_helper.py index 3f41fac..51161aa 100644 --- a/pytest_tests/helpers/sbercloud_helper.py +++ b/pytest_tests/helpers/sbercloud_helper.py @@ -38,6 +38,13 @@ class SberCloudConfig: class SberCloud: + """ + Manages resources in Sbercloud via API. + + API reference: + https://docs.sbercloud.ru/terraform/ug/topics/quickstart.html + https://support.hc.sbercloud.ru/en-us/api/ecs/en-us_topic_0020212668.html + """ def __init__(self, config: SberCloudConfig) -> None: self.config = config self.ecs_url = None diff --git a/pytest_tests/helpers/service_helper.py b/pytest_tests/helpers/service_helper.py index 01f3b0e..fdea9c4 100644 --- a/pytest_tests/helpers/service_helper.py +++ b/pytest_tests/helpers/service_helper.py @@ -81,13 +81,13 @@ class CloudVmStorageServiceHelper: def stop_node(self, node_name: str) -> None: with _create_ssh_client(node_name) as ssh_client: - cmd = f"systemctl stop {self.STORAGE_SERVICE}" + cmd = f"sudo systemctl stop {self.STORAGE_SERVICE}" output = ssh_client.exec_with_confirmation(cmd, [""]) logger.info(f"Stop command output: {output.stdout}") def start_node(self, node_name: str) -> None: with _create_ssh_client(node_name) as ssh_client: - cmd = f"systemctl start {self.STORAGE_SERVICE}" + cmd = f"sudo systemctl start {self.STORAGE_SERVICE}" output = ssh_client.exec_with_confirmation(cmd, [""]) logger.info(f"Start command output: {output.stdout}") @@ -95,7 +95,7 @@ class CloudVmStorageServiceHelper: expected_state = 'active (running)' with _create_ssh_client(node_name) as ssh_client: for __attempt in range(10): - output = ssh_client.exec(f'systemctl status {self.STORAGE_SERVICE}') + output = ssh_client.exec(f'sudo systemctl status {self.STORAGE_SERVICE}') if expected_state in output.stdout: return time.sleep(3) @@ -113,17 +113,17 @@ class CloudVmStorageServiceHelper: # Copy wallet content on storage node host with open(wallet_path, "r") as file: wallet = file.read() - remote_wallet_path = "/tmp/{node_name}-wallet.json" + remote_wallet_path = f"/tmp/{node_name}-wallet.json" ssh_client.exec_with_confirmation(f"echo '{wallet}' > {remote_wallet_path}", [""]) # Put config on storage node host - remote_config_path = "/tmp/{node_name}-config.yaml" + remote_config_path = f"/tmp/{node_name}-config.yaml" remote_config = 'password: ""' ssh_client.exec_with_confirmation(f"echo '{remote_config}' > {remote_config_path}", [""]) # Execute command cmd = ( - f'{STORAGE_NODE_BIN_PATH}/neofs-cli {command} --endpoint {control_endpoint} ' + f'sudo {STORAGE_NODE_BIN_PATH}/neofs-cli {command} --endpoint {control_endpoint} ' f'--wallet {remote_wallet_path} --config {remote_config_path}' ) output = ssh_client.exec_with_confirmation(cmd, [""]) @@ -131,7 +131,7 @@ class CloudVmStorageServiceHelper: def delete_node_data(self, node_name: str) -> None: with _create_ssh_client(node_name) as ssh_client: - ssh_client.exec('rm -rf /srv/neofs/*') + ssh_client.exec("sudo rm -rf /srv/neofs/*") def get_binaries_version(self, binaries: list = None) -> dict: default_binaries = [ @@ -153,7 +153,7 @@ class CloudVmStorageServiceHelper: with _create_ssh_client(node_name) as ssh_client: for binary in binaries: try: - out = ssh_client.exec(f'{binary} --version').stdout + out = ssh_client.exec(f'sudo {binary} --version').stdout except AssertionError as err: logger.error(f'Can not get version for {binary} because of\n{err}') version_map[binary] = 'Can not get version' @@ -192,7 +192,8 @@ class RemoteDevEnvStorageServiceHelper(LocalDevEnvStorageServiceHelper): # SSH into remote machine and delete files in host directory that is mounted as docker volume with _create_ssh_client(node_name) as ssh_client: - ssh_client.exec(f'rm -rf {volume_path}/*') + # TODO: add sudo prefix after we change a user + ssh_client.exec(f"rm -rf {volume_path}/*") def get_storage_service_helper(): diff --git a/pytest_tests/helpers/ssh_helper.py b/pytest_tests/helpers/ssh_helper.py index ffc0622..6a99bf0 100644 --- a/pytest_tests/helpers/ssh_helper.py +++ b/pytest_tests/helpers/ssh_helper.py @@ -77,8 +77,6 @@ class HostClient: self.create_connection(self.SSH_CONNECTION_ATTEMPTS) def exec(self, cmd: str, verify=True, timeout=90) -> SSHCommand: - if self.login != 'root': - cmd = f'sudo {cmd}' cmd_result = self._inner_exec(cmd, timeout) if verify: assert cmd_result.rc == 0, f'Non zero rc from command: "{cmd}"' @@ -86,8 +84,6 @@ class HostClient: @log_command def exec_with_confirmation(self, cmd: str, confirmation: list, verify=True, timeout=90) -> SSHCommand: - if self.login != "root": - cmd = f"sudo {cmd}" ssh_stdin, ssh_stdout, ssh_stderr = self.ssh_client.exec_command(cmd, timeout=timeout) for line in confirmation: if not line.endswith('\n'): @@ -176,7 +172,7 @@ class HostClient: else: logging.info( f"Trying to connect to host {self.ip} as {self.login} using password " - f"{self.password[:2] + '***' if self.password else ''} (attempt {attempt})" + f"(attempt {attempt})" ) self.ssh_client.connect( hostname=self.ip, diff --git a/pytest_tests/testsuites/failovers/test_failover_network.py b/pytest_tests/testsuites/failovers/test_failover_network.py index fd501f3..784663f 100644 --- a/pytest_tests/testsuites/failovers/test_failover_network.py +++ b/pytest_tests/testsuites/failovers/test_failover_network.py @@ -25,8 +25,8 @@ blocked_hosts = [] @pytest.fixture(autouse=True) @allure.step('Install iptables if needed') def install_iptables_if_needed(): - check_command = 'iptables --version' - install_command = 'apt-get --yes install iptables' + check_command = 'sudo iptables --version' + install_command = 'sudo apt-get --yes install iptables' for node_config in NEOFS_NETMAP_DICT.values(): host = node_config.get('rpc').split(':')[0] client = HostClient(ip=host, login=STORAGE_NODE_SSH_USER,