def _new_session(self): """ Build a new server session. """ port = self.port prompt = self.prompt host = self.server_ip client = self.client username = self.server_user password = self.server_pwd try: session = remote.wait_for_login(client, host, port, username, password, prompt) except remote.LoginTimeoutError: raise exceptions.TestError( "Got a timeout error when login to server.") except remote.LoginAuthenticationError: raise exceptions.TestError( "Authentication failed to login to server.") except remote.LoginProcessTerminatedError: raise exceptions.TestError( "Host terminates during login to server.") except remote.LoginError: raise exceptions.TestError( "Some error occurs login to client server.") return session
def __init__(self, client="ssh", host=None, port="22", username="******", password=None, prompt=r"[\#\$]\s*$", linesep="\n", log_filename=None, timeout=240, internal_timeout=10, session=None, preferred_authenticaton='password'): """ Initialization of RemoteRunner. Init a session login to remote host or guest. :param client: The client to use ('ssh', 'telnet' or 'nc') :param host: Hostname or IP address :param port: Port to connect to :param username: Username (if required) :param password: Password (if required) :param prompt: Shell prompt (regular expression) :param linesep: The line separator to use when sending lines (e.g. '\\n' or '\\r\\n') :param log_filename: If specified, log all output to this file :param timeout: Total time duration to wait for a successful login :param internal_timeout: The maximal time duration (in seconds) to wait for each step of the login procedure (e.g. the "Are you sure" prompt or the password prompt) :param session: An existing session :param preferred_authenticaton: The preferred authentication of SSH connection :see: remote.wait_for_login() :raise: Whatever remote.wait_for_login() raises """ if session is None: if host is None: raise exceptions.TestError( "Neither host, nor session was defined!") self.session = remote.wait_for_login( client, host, port, username, password, prompt, linesep, log_filename, timeout, internal_timeout, preferred_authenticaton=preferred_authenticaton) else: self.session = session # Init stdout pipe and stderr pipe. self.stdout_pipe = tempfile.mktemp() self.stderr_pipe = tempfile.mktemp()
def share_remote_objects(session, control_path, host="localhost", port=9090, os_type="windows", extra_params=None): """ Create and share remote objects from a remote location over the network. :param session: remote session to the platform :type session: RemoteSession :param str control_path: path to the control on the host :param str host: ip address of the remote sharing server :param int port: port of the remote sharing server :param str os_type: OS type of the session, either "linux" or "windows" :param extra_params: extra parameters to pass to the remote object sharing control file (sismilarly to subcontrol setting above), with keys usually prepended with "ro_" prefix :type extra_params: {str, str} :returns: newly created middleware session for the remote object server :rtype: :py:class:`RemoteSession` :raises: :py:class:`RuntimeError` if the object server failed to start In comparison to :py:func:`share_local_object`, this function fires up a name server from a second spawned session (not remote util call) and uses static (template) control as a remote object server which has to be preprogrammed but thus also customized (e.g. sharing multiple objects). In comparison to :py:func:`share_local_objects`, this function is not an internal implementation sharing everything on the other side but only what is dicated by the remote object server module and thus its creator. .. note:: Created and works specifically for Windows and Linux. """ LOG.info("Sharing the remote objects over the network") extra_params = {} if extra_params is None else extra_params # setup remote objects server LOG.info("Starting nameserver for the remote objects") cmd = "python -m Pyro4.naming -n %s -p %s" % (host, port) session.cmd("START " + cmd if os_type == "windows" else cmd + " &") LOG.info("Starting the server daemon for the remote objects") # ..todo:: later on we can dynamize this further depending on usage of this alternative function transfer_client = "rss" if os_type == "windows" else "scp" transfer_port = 10023 if os_type == "windows" else 22 local_path = set_subcontrol_parameter(control_path, "ro_server_ip", host) # optional parameters (set only if present and/or available) for key in extra_params.keys(): local_path = set_subcontrol_parameter(local_path, key, extra_params[key]) remote_path = os.path.join(REMOTE_CONTROL_DIR, os.path.basename(control_path)) # NOTE: since we are creating the path in Linux but use it in Windows, # we replace some of the backslashes if os_type == "windows": remote_path = remote_path.replace("/", "\\") remote.copy_files_to(session.host, transfer_client, session.username, session.password, transfer_port, local_path, remote_path, timeout=10) middleware_session = remote.wait_for_login(session.client, session.host, session.port, session.username, session.password, session.prompt, session.linesep) middleware_session.set_status_test_command(session.status_test_command) middleware_session.set_output_func(LOG.info) middleware_session.set_output_params(()) middleware_session.sendline("python %s" % remote_path) # HACK: not the best way to do this but the stderr and stdout are mixed and we # cannot get the exit status so we rely on the mixed stdout/stderr output output, attempts = "", 30 while "Remote objects shared over the network" not in output: output = middleware_session.get_output() LOG.debug(output) if attempts <= 0 or "Traceback (most recent call last):" in output: raise RuntimeError("The remote objects server failed to start") attempts -= 1 time.sleep(1) Pyro4.config.NS_HOST = host logging.getLogger("Pyro4").setLevel(10) return middleware_session
def setup_or_cleanup_iptables_rules(cls, rules, params=None, cleanup=False): """ Setup or cleanup for iptable rules, it can be locally or remotely :param rules: list of rules :param params: dict with server details :param cleanup: Boolean value, true to cleanup, false to setup """ commands = [] # check the existing iptables rules in remote or local machine iptable_check_cmd = "iptables -S" if params: server_ip = params.get("server_ip") server_user = params.get("server_user", "root") server_pwd = params.get("server_pwd") server_session = remote.wait_for_login('ssh', server_ip, '22', server_user, server_pwd, r"[\#\$]\s*$") cmd_output = server_session.cmd_status_output(iptable_check_cmd) if (cmd_output[0] == 0): exist_rules = cmd_output[1].strip().split('\n') else: server_session.close() raise exceptions.TestError("iptables fails for command " "remotely %s" % iptable_check_cmd) else: try: cmd_output = process.run(iptable_check_cmd, shell=True).stdout_text exist_rules = cmd_output.strip().split('\n') except process.CmdError as info: raise exceptions.TestError("iptables fails for command " "locally %s" % iptable_check_cmd) # check rules whether it is really needed to be added or cleaned for rule in rules: flag = False for exist_rule in exist_rules: if rule in exist_rule: logging.debug("Rule: %s exist in iptables", rule) flag = True if cleanup: logging.debug("cleaning rule: %s", rule) commands.append("iptables -D %s" % rule) if not flag and not cleanup: logging.debug("Adding rule: %s", rule) commands.append("iptables -I %s" % rule) # Once rules are filtered, then it is executed in remote or local # machine for command in commands: if params: cmd_output = server_session.cmd_status_output(command) if (cmd_output[0] != 0): server_session.close() raise exceptions.TestError("iptables command failed " "remotely %s" % command) else: logging.debug("iptable command success %s", command) else: try: cmd_output = process.run(command, shell=True).stdout_text logging.debug("iptable command success %s", command) except process.CmdError as info: raise exceptions.TestError("iptables fails for command " "locally %s" % command) # cleanup server session if params: server_session.close()
def run(test, params, env): """ Test remote access with TLS connection and multiple CA certificates """ config_files = [] server_files = [] client_files = [] ca_cert_file = None server_info = get_server_details(params) server_session = remote.wait_for_login('ssh', server_info['ip'], '22', server_info['user'], server_info['pwd'], r"[\#\$]\s*$") client_info = get_client_details(params) client_session = remote.wait_for_login('ssh', client_info['ip'], '22', client_info['user'], client_info['pwd'], r"[\#\$]\s*$") try: # NOTE: The Test can be divided to multiple parts, however the first # part - setup is a time consuming and it is therefore better to do it # once only. certs_dict = prepare_a_certs_dictionary(server_info) certs_dir = os.getcwd() prepare_info_files(certs_dict, certs_dir) generate_keys(certs_dir) generate_certificates(certs_dict, certs_dir) concatenate_certificates(certs_dir, 'carootcert.pem', 'cachild1cert.pem', 'cachild2cert.pem') ca_cert_file = copy_ca_certs_to_hosts(certs_dir, server_info, client_info) server_files = prepare_certs_and_keys_on_host(server_session, server_info, certs_dir, 'server1') config_files = setup_libvirt_on_server(server_session, server_info) stop_iptables() allow_port_in_fw(server_session) restart_libvirtd_on_server(server_session) client_files = prepare_certs_and_keys_on_host(client_session, client_info, certs_dir, 'client1') # Connect to server1 hypervisor on client1 connect_to_remote(server_info) # Test with other CA certificates order for new_order in [ ['cachild2cert.pem', 'carootcert.pem', 'cachild1cert.pem'], ['cachild1cert.pem', 'carootcert.pem', 'cachild2cert.pem'], ]: concatenate_certificates(certs_dir, *new_order) copy_ca_certs_to_hosts(certs_dir, server_info, client_info) restart_libvirtd_on_server(server_session) connect_to_remote(server_info) # Test with missing issuing CA concatenate_certificates(certs_dir, 'cachild2cert.pem', 'carootcert.pem') # Publish to server only copy_ca_certs_to_hosts(certs_dir, server_info) # Start reading the /var/log/messages on server tail_messages = get_log(server_info) restart_libvirtd_on_server(server_session) err_msg = params.get('err_msg') output = tail_messages.get_output() tail_messages.close() if err_msg not in output: test.fail("Unexpected output of the /var/log/messages on remote " "server: {}".format(output)) # Fix the CA certificates concatenate_certificates(certs_dir, 'cachild2cert.pem', 'carootcert.pem', 'cachild1cert.pem') # Copy to server copy_ca_certs_to_hosts(certs_dir, server_info) restart_libvirtd_on_server(server_session) # Check if the connection can be established again connect_to_remote(server_info) # Create an invalid CA cert for client concatenate_certificates(certs_dir, 'cachild2cert.pem', 'carootcert.pem') # Copy to client copy_ca_certs_to_hosts(certs_dir, client_info) connect_to_remote(server_info, err_msg) except Exception as e: test.fail('Unexpected failure: {}'.format(e)) finally: if config_files: for config in config_files: del config if server_files: for file_path in server_files: server_session.cmd_status_output('rm -f {}'.format(file_path)) if client_files: for file_path in client_files: client_session.cmd_status_output('rm -f {}'.format(file_path)) if ca_cert_file: server_session.cmd_status_output('rm -f {}'.format(ca_cert_file)) client_session.cmd_status_output('rm -f {}'.format(ca_cert_file))