Beispiel #1
0
    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
Beispiel #2
0
    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()
Beispiel #3
0
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
Beispiel #4
0
    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))