Beispiel #1
0
def run(test, params, env):
    """
    Test remote access with TCP, TLS connection
    """

    test_dict = dict(params)
    vm_name = test_dict.get("main_vm")
    status_error = test_dict.get("status_error", "no")
    allowed_dn_str = params.get("tls_allowed_dn_list")
    if allowed_dn_str:
        allowed_dn_list = []
        if not libvirt_version.version_compare(1, 0, 0):
            # Reverse the order in the dn list to workaround the
            # feature changes between RHEL 6 and RHEL 7
            dn_list = allowed_dn_str.split(",")
            dn_list.reverse()
            allowed_dn_str = ','.join(dn_list)
        allowed_dn_list.append(allowed_dn_str)
        test_dict['tls_allowed_dn_list'] = allowed_dn_list
    transport = test_dict.get("transport")
    plus = test_dict.get("conn_plus", "+")
    config_ipv6 = test_dict.get("config_ipv6", "no")
    tls_port = test_dict.get("tls_port", "")
    listen_addr = test_dict.get("listen_addr", "0.0.0.0")
    ssh_port = test_dict.get("ssh_port", "")
    tcp_port = test_dict.get("tcp_port", "")
    server_ip = test_dict.get("server_ip")
    server_user = test_dict.get("server_user")
    server_pwd = test_dict.get("server_pwd")
    no_any_config = params.get("no_any_config", "no")
    sasl_user_pwd = test_dict.get("sasl_user_pwd")
    sasl_allowed_users = test_dict.get("sasl_allowed_users")
    server_cn = test_dict.get("server_cn")
    custom_pki_path = test_dict.get("custom_pki_path")
    rm_client_key_cmd = test_dict.get("remove_client_key_cmd")
    rm_client_cert_cmd = test_dict.get("remove_client_cert_cmd")
    ca_cn_new = test_dict.get("ca_cn_new")
    no_verify = test_dict.get("no_verify", "no")
    ipv6_addr_des = test_dict.get("ipv6_addr_des")
    tls_sanity_cert = test_dict.get("tls_sanity_cert")
    restart_libvirtd = test_dict.get("restart_libvirtd", "yes")
    diff_virt_ver = test_dict.get("diff_virt_ver", "no")
    driver = test_dict.get("test_driver", "qemu")
    uri_path = test_dict.get("uri_path", "/system")
    virsh_cmd = params.get("virsh_cmd", "list")
    action = test_dict.get("libvirtd_action", "restart")
    uri_user = test_dict.get("uri_user", "")
    unix_sock_dir = test_dict.get("unix_sock_dir")
    mkdir_cmd = test_dict.get("mkdir_cmd")
    rmdir_cmd = test_dict.get("rmdir_cmd")
    adduser_cmd = test_dict.get("adduser_cmd")
    deluser_cmd = test_dict.get("deluser_cmd")
    auth_conf = test_dict.get("auth_conf")
    auth_conf_cxt = test_dict.get("auth_conf_cxt")
    polkit_pkla = test_dict.get("polkit_pkla")
    polkit_pkla_cxt = test_dict.get("polkit_pkla_cxt")
    ssh_setup = test_dict.get("ssh_setup", "no")
    tcp_setup = test_dict.get("tcp_setup", "no")
    tls_setup = test_dict.get("tls_setup", "no")
    unix_setup = test_dict.get("unix_setup", "no")
    ssh_recovery = test_dict.get("ssh_auto_recovery", "yes")
    tcp_recovery = test_dict.get("tcp_auto_recovery", "yes")
    tls_recovery = test_dict.get("tls_auto_recovery", "yes")
    unix_recovery = test_dict.get("unix_auto_recovery", "yes")

    port = ""
    # extra URI arguments
    extra_params = ""
    # it's used to clean up SSH, TLS, TCP, UNIX and SASL objs later
    objs_list = []
    # redirect LIBVIRT_DEBUG log into test log later
    test_dict["logfile"] = test.logfile

    # Make sure all of parameters are assigned a valid value
    check_parameters(test_dict, test)

    # only simply connect libvirt daemon then return
    if no_any_config == "yes":
        test_dict["uri"] = "%s%s%s://%s" % (driver, plus, transport, uri_path)
        remote_access(test_dict, test)
        return

    # append extra 'pkipath' argument to URI if exists
    if custom_pki_path:
        extra_params = "?pkipath=%s" % custom_pki_path

    # append extra 'no_verify' argument to URI if exists
    if no_verify == "yes":
        extra_params = "?no_verify=1"

    # append extra 'socket' argument to URI if exists
    if unix_sock_dir:
        extra_params = "?socket=%s/libvirt-sock" % unix_sock_dir

    # generate auth.conf and default under the '/etc/libvirt'
    if auth_conf_cxt and auth_conf:
        cmd = "echo -e '%s' > %s" % (auth_conf_cxt, auth_conf)
        process.system(cmd, ignore_status=True, shell=True)

    # generate polkit_pkla and default under the
    # '/etc/polkit-1/localauthority/50-local.d/'
    if polkit_pkla_cxt and polkit_pkla:
        cmd = "echo -e '%s' > %s" % (polkit_pkla_cxt, polkit_pkla)
        process.system(cmd, ignore_status=True, shell=True)

    # generate remote IP
    if config_ipv6 == "yes" and ipv6_addr_des:
        remote_ip = "[%s]" % ipv6_addr_des
    elif config_ipv6 != "yes" and server_cn:
        remote_ip = server_cn
    elif config_ipv6 != "yes" and ipv6_addr_des:
        remote_ip = "[%s]" % ipv6_addr_des
    elif server_ip and transport != "unix":
        remote_ip = server_ip
    else:
        remote_ip = ""

    # get URI port
    if tcp_port != "":
        port = ":" + tcp_port

    if tls_port != "":
        port = ":" + tls_port

    if ssh_port != "" and not ipv6_addr_des:
        port = ":" + ssh_port

    # generate URI
    uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user,
                                   remote_ip, port, uri_path, extra_params)
    test_dict["uri"] = uri

    logging.debug("The final test dict:\n<%s>", test_dict)

    if virsh_cmd == "start" and transport != "unix":
        session = remote.wait_for_login("ssh", server_ip, "22", "root",
                                        server_pwd, "#")
        cmd = "virsh domstate %s" % vm_name
        status, output = session.cmd_status_output(cmd)
        if status:
            session.close()
            test.cancel(output)

        session.close()

    try:
        # setup IPv6
        if config_ipv6 == "yes":
            ipv6_obj = IPv6Manager(test_dict)
            objs_list.append(ipv6_obj)
            ipv6_obj.setup()

        # compare libvirt version if needs
        if diff_virt_ver == "yes":
            compare_virt_version(server_ip, server_user, server_pwd, test)

        # setup SSH
        if transport == "ssh" or ssh_setup == "yes":
            if not test_dict.get("auth_pwd"):
                ssh_obj = SSHConnection(test_dict)
                if ssh_recovery == "yes":
                    objs_list.append(ssh_obj)
                # setup test environment
                ssh_obj.conn_setup()

        # setup TLS
        if transport == "tls" or tls_setup == "yes":
            tls_obj = TLSConnection(test_dict)
            if tls_recovery == "yes":
                objs_list.append(tls_obj)
            # reserve cert path
            tmp_dir = tls_obj.tmp_dir
            # setup test environment
            if tls_sanity_cert == "no":
                # only setup CA and client
                tls_obj.conn_setup(False, True)
            else:
                # setup CA, server and client
                tls_obj.conn_setup()

        # setup TCP
        if transport == "tcp" or tcp_setup == "yes":
            tcp_obj = TCPConnection(test_dict)
            if tcp_recovery == "yes":
                objs_list.append(tcp_obj)
            # setup test environment
            tcp_obj.conn_setup()

        # create a directory if needs
        if mkdir_cmd:
            process.system(mkdir_cmd, ignore_status=True, shell=True)

        # setup UNIX
        if transport == "unix" or unix_setup == "yes":
            unix_obj = UNIXConnection(test_dict)
            if unix_recovery == "yes":
                objs_list.append(unix_obj)
            # setup test environment
            unix_obj.conn_setup()

        # need to restart libvirt service for negative testing
        if restart_libvirtd == "no":
            remotely_control_libvirtd(server_ip, server_user, server_pwd,
                                      action, status_error)

        # check TCP/IP listening by service
        if restart_libvirtd != "no" and transport != "unix":
            service = 'libvirtd'
            if transport == "ssh":
                service = 'ssh'

            check_listening_port_remote_by_service(server_ip, server_user,
                                                   server_pwd, service, port,
                                                   listen_addr)

        # remove client certifications if exist, only for TLS negative testing
        if rm_client_key_cmd:
            process.system(rm_client_key_cmd, ignore_status=True, shell=True)

        if rm_client_cert_cmd:
            process.system(rm_client_cert_cmd, ignore_status=True, shell=True)

        # add user to specific group
        if adduser_cmd:
            process.system(adduser_cmd, ignore_status=True, shell=True)

        # change /etc/pki/libvirt/servercert.pem then
        # restart libvirt service on the remote host
        if tls_sanity_cert == "no" and ca_cn_new:
            test_dict['ca_cn'] = ca_cn_new
            test_dict['ca_cakey_path'] = tmp_dir
            test_dict['scp_new_cacert'] = 'no'
            tls_obj_new = TLSConnection(test_dict)
            test_dict['tls_obj_new'] = tls_obj_new
            # only setup new CA and server
            tls_obj_new.conn_setup(True, False)

        # setup SASL certification
        # From libvirt-3.2.0, the default sasl change from
        # DIGEST-MD5 to GSSAPI. "sasl_user" is discarded.
        # More details: https://libvirt.org/auth.html#ACL_server_kerberos
        if sasl_user_pwd and not libvirt_version.version_compare(3, 2, 0):
            # covert string tuple and list to python data type
            sasl_user_pwd = eval(sasl_user_pwd)
            if sasl_allowed_users:
                sasl_allowed_users = eval(sasl_allowed_users)

            # create a sasl user
            sasl_obj = SASL(test_dict)
            objs_list.append(sasl_obj)
            sasl_obj.setup()

            for sasl_user, sasl_pwd in sasl_user_pwd:
                # need't authentication if the auth.conf is configured by user
                if not auth_conf:
                    test_dict["auth_user"] = sasl_user
                    test_dict["auth_pwd"] = sasl_pwd
                    logging.debug("sasl_user, sasl_pwd = "
                                  "(%s, %s)", sasl_user, sasl_pwd)

                if sasl_allowed_users and sasl_user not in sasl_allowed_users:
                    test_dict["status_error"] = "yes"
                patterns_extra_dict = {"authentication name": sasl_user}
                test_dict["patterns_extra_dict"] = patterns_extra_dict
                remote_access(test_dict, test)
        else:
            remote_access(test_dict, test)

    finally:
        # recovery test environment
        # Destroy the VM after all test are done
        if vm_name:
            vm = env.get_vm(vm_name)
            if vm and vm.is_alive():
                vm.destroy(gracefully=False)

        if rmdir_cmd:
            process.system(rmdir_cmd, ignore_status=True, shell=True)

        if deluser_cmd:
            process.system(deluser_cmd, ignore_status=True, shell=True)

        if auth_conf and os.path.isfile(auth_conf):
            os.unlink(auth_conf)

        if polkit_pkla and os.path.isfile(polkit_pkla):
            os.unlink(polkit_pkla)

        cleanup(objs_list)
Beispiel #2
0
class NFSClient(object):
    """
    NFSClient class for handle nfs remotely mount and umount.
    """
    def __init__(self, params):
        self.nfs_client_ip = params.get("nfs_client_ip")
        # To Avoid host key verification failure
        ret = process.run("ssh-keygen -R %s" % self.nfs_client_ip,
                          ignore_status=True)
        stderr = ret.stderr_text
        if ret.exit_status and "No such file or directory" not in stderr:
            raise exceptions.TestFail("Failed to update host key: %s" % stderr)
        # Setup SSH connection
        self.ssh_obj = SSHConnection(params)
        ssh_timeout = int(params.get("ssh_timeout", 10))
        self.ssh_obj.conn_setup(timeout=ssh_timeout)

        self.params = params
        self.mkdir_mount_remote = False
        self.mount_dir = params.get("nfs_mount_dir")
        self.mount_options = params.get("nfs_mount_options")
        self.mount_src = params.get("nfs_mount_src")
        self.nfs_server_ip = params.get("nfs_server_ip")
        self.ssh_user = params.get("ssh_username", "root")
        self.remote_nfs_mount = params.get("remote_nfs_mount", "yes")
        self.ssh_hostkey_check = params.get("ssh_hostkey_check", "no") == "yes"
        self.ssh_cmd = "ssh %s@%s " % (self.ssh_user, self.nfs_client_ip)
        if not self.ssh_hostkey_check:
            self.ssh_cmd += "-o StrictHostKeyChecking=no "

    def is_mounted(self):
        """
        Check the NFS is mounted or not.

        :return: If the src is mounted as expect
        :rtype: Boolean
        """
        find_mountpoint_cmd = "mount | grep -E '.*%s.*%s.*'" % (self.mount_src,
                                                                self.mount_dir)
        cmd = self.ssh_cmd + "'%s'" % find_mountpoint_cmd
        logging.debug("The command: %s", cmd)
        status, output = process.getstatusoutput(cmd)
        if status:
            logging.debug("The command result: <%s:%s>", status, output)
            return False
        return True

    def setup(self):
        """
        Setup NFS client.
        """
        # Mount sharing directory to local host
        # it has been covered by class Nfs

        # Mount sharing directory to remote host
        if self.remote_nfs_mount == "yes":
            # stale file mounted causes test to fail instead
            # unmount it and perform the setup
            if self.is_mounted():
                self.umount()
            self.setup_remote()

    def umount(self):
        """
        Unmount the mount directory in remote host
        """
        logging.debug("Umount %s from %s" %
                      (self.mount_dir, self.nfs_client_ip))
        umount_cmd = self.ssh_cmd + "'umount -l %s'" % self.mount_dir
        try:
            process.system(umount_cmd, verbose=True)
        except process.CmdError:
            raise exceptions.TestFail("Failed to run: %s" % umount_cmd)

    def cleanup(self, ssh_auto_recover=False):
        """
        Cleanup NFS client.
        """
        self.umount()
        if self.mkdir_mount_remote:
            rmdir_cmd = self.ssh_cmd + "'rm -rf %s'" % self.mount_dir
            try:
                process.system(rmdir_cmd, verbose=True)
            except process.CmdError:
                raise exceptions.TestFail("Failed to run: %s" % rmdir_cmd)

        if self.is_mounted():
            raise exceptions.TestFail("Failed to umount %s" % self.mount_dir)

        # Recover SSH connection
        if ssh_auto_recover:
            self.ssh_obj.auto_recover = ssh_auto_recover
            del self.ssh_obj

    def firewall_to_permit_nfs(self):
        """
        Method to configure firewall to permit NFS to be mounted
        from remote host
        """
        # Check firewall in host permit nfs service to mount from remote server
        try:
            firewalld = service.Factory.create_service("firewalld")
            if not firewalld.status():
                firewalld.start()
            firewall_cmd = "firewall-cmd --list-all | grep services:"
            try:
                ret = process.run(firewall_cmd, shell=True)
                if not ret.exit_status:
                    firewall_services = ret.stdout_text.split(
                        ':')[1].strip().split(' ')
                    if 'nfs' not in firewall_services:
                        service_cmd = "firewall-cmd --permanent --zone=public "
                        service_cmd += "--add-service=nfs"
                        ret = process.run(service_cmd, shell=True)
                        if ret.exit_status:
                            logging.error(
                                "nfs service not added in firewall: "
                                "%s", ret.stdout_text)
                        else:
                            logging.debug("nfs service added to firewall "
                                          "sucessfully")
                            firewalld.restart()
                    else:
                        logging.debug(
                            "nfs service already permitted by firewall")
            except process.CmdError:
                # For RHEL 6 based system firewall-cmd is not available
                logging.debug("Using iptables to permit NFS service")
                nfs_ports = []
                rule_list = []
                nfsd = service.Factory.create_service("nfs")
                rpcd = service.Factory.create_service("rpcbind")
                iptables = service.Factory.create_service("iptables")
                nfs_sysconfig = self.params.get("nfs_sysconfig_path",
                                                "/etc/sysconfig/nfs")
                tcp_port = self.params.get("nfs_tcp_port", "32803")
                udp_port = self.params.get("nfs_udp_port", "32769")
                mountd_port = self.params.get("nfs_mountd_port", "892")
                subnet_mask = self.params.get("priv_subnet", "192.168.2.0/24")
                nfs_ports.append("LOCKD_TCPPORT=%s" % tcp_port)
                nfs_ports.append("LOCKD_UDPPORT=%s" % udp_port)
                nfs_ports.append("MOUNTD_PORT=%s" % mountd_port)
                cmd_output = process.run("cat %s" % nfs_sysconfig,
                                         shell=True).stdout_text
                exist_ports = cmd_output.strip().split('\n')
                # check if the ports are already configured, if not then add it
                for each_port in nfs_ports:
                    if each_port not in exist_ports:
                        process.run("echo '%s' >> %s" %
                                    (each_port, nfs_sysconfig),
                                    shell=True)
                rpcd.restart()
                nfsd.restart()
                rule_temp = "INPUT -m state --state NEW -p %s -m multiport "
                rule_temp += "--dport 111,892,2049,%s -s %s -j ACCEPT"
                rule = rule_temp % ("tcp", tcp_port, subnet_mask)
                rule_list.append(rule)
                rule = rule_temp % ("udp", udp_port, subnet_mask)
                rule_list.append(rule)
                Iptables.setup_or_cleanup_iptables_rules(rule_list)
                iptables.restart()
        except Exception as info:
            logging.error("Firewall setting to add nfs service "
                          "failed: %s", info)

    def setup_remote(self):
        """
        Mount sharing directory to remote host.
        """
        check_mount_dir_cmd = self.ssh_cmd + "'ls -d %s'" % self.mount_dir
        logging.debug("To check if the %s exists", self.mount_dir)
        output = process.getoutput(check_mount_dir_cmd)
        if re.findall("No such file or directory", output, re.M):
            mkdir_cmd = self.ssh_cmd + "'mkdir -p %s'" % self.mount_dir
            logging.debug("Prepare to create %s", self.mount_dir)
            s, o = process.getstatusoutput(mkdir_cmd)
            if s != 0:
                raise exceptions.TestFail("Failed to run %s: %s" %
                                          (mkdir_cmd, o))
            self.mkdir_mount_remote = True

        if self.params.get("firewall_to_permit_nfs", "yes") == "yes":
            if distro.detect().name != "Ubuntu":
                self.firewall_to_permit_nfs()

        self.mount_src = "%s:%s" % (self.nfs_server_ip, self.mount_src)
        logging.debug("Mount %s to %s" % (self.mount_src, self.mount_dir))
        mount_cmd = "mount -t nfs %s %s" % (self.mount_src, self.mount_dir)
        if self.mount_options:
            mount_cmd += " -o %s" % self.mount_options
        try:
            cmd = "%s '%s'" % (self.ssh_cmd, mount_cmd)
            process.system(cmd, verbose=True)
        except process.CmdError:
            raise exceptions.TestFail("Failed to run: %s" % cmd)

        # Check if the sharing directory is mounted
        if not self.is_mounted():
            raise exceptions.TestFail(
                "Failed to mount from %s to %s" % self.mount_src,
                self.mount_dir)
def run(test, params, env):
    """
    Test remote access with TCP, TLS connection
    """

    test_dict = dict(params)
    pattern = test_dict.get("filter_pattern", "")
    if ('@LIBVIRT' in pattern and
            distro.detect().name == 'rhel' and
            int(distro.detect().version) < 8):
        test.cancel("The test {} is not supported on current OS({}{}<8.0) as "
                    "the keyword @LIBVIRT is not supported by gnutls on this "
                    "OS.".format(test.name, distro.detect().name,
                                 distro.detect().version))
    vm_name = test_dict.get("main_vm")
    status_error = test_dict.get("status_error", "no")
    allowed_dn_str = params.get("tls_allowed_dn_list")
    if allowed_dn_str:
        allowed_dn_list = []
        if not libvirt_version.version_compare(1, 0, 0):
            # Reverse the order in the dn list to workaround the
            # feature changes between RHEL 6 and RHEL 7
            dn_list = allowed_dn_str.split(",")
            dn_list.reverse()
            allowed_dn_str = ','.join(dn_list)
        allowed_dn_list.append(allowed_dn_str)
        test_dict['tls_allowed_dn_list'] = allowed_dn_list
    transport = test_dict.get("transport")
    plus = test_dict.get("conn_plus", "+")
    config_ipv6 = test_dict.get("config_ipv6", "no")
    tls_port = test_dict.get("tls_port", "")
    listen_addr = test_dict.get("listen_addr", "0.0.0.0")
    ssh_port = test_dict.get("ssh_port", "")
    tcp_port = test_dict.get("tcp_port", "")
    server_ip = test_dict.get("server_ip")
    server_user = test_dict.get("server_user")
    server_pwd = test_dict.get("server_pwd")
    no_any_config = params.get("no_any_config", "no")
    sasl_type = test_dict.get("sasl_type", "gssapi")
    sasl_user_pwd = test_dict.get("sasl_user_pwd")
    sasl_allowed_users = test_dict.get("sasl_allowed_users")
    server_cn = test_dict.get("server_cn")
    custom_pki_path = test_dict.get("custom_pki_path")
    rm_client_key_cmd = test_dict.get("remove_client_key_cmd")
    rm_client_cert_cmd = test_dict.get("remove_client_cert_cmd")
    ca_cn_new = test_dict.get("ca_cn_new")
    no_verify = test_dict.get("no_verify", "no")
    ipv6_addr_des = test_dict.get("ipv6_addr_des")
    tls_sanity_cert = test_dict.get("tls_sanity_cert")
    restart_libvirtd = test_dict.get("restart_libvirtd", "yes")
    diff_virt_ver = test_dict.get("diff_virt_ver", "no")
    driver = test_dict.get("test_driver", "qemu")
    uri_path = test_dict.get("uri_path", "/system")
    virsh_cmd = params.get("virsh_cmd", "list")
    action = test_dict.get("libvirtd_action", "restart")
    uri_user = test_dict.get("uri_user", "")
    uri_aliases = test_dict.get("uri_aliases", "")
    uri_default = test_dict.get("uri_default", "")
    unix_sock_dir = test_dict.get("unix_sock_dir")
    mkdir_cmd = test_dict.get("mkdir_cmd")
    rmdir_cmd = test_dict.get("rmdir_cmd")
    adduser_cmd = test_dict.get("adduser_cmd")
    deluser_cmd = test_dict.get("deluser_cmd")
    auth_conf = test_dict.get("auth_conf")
    auth_conf_cxt = test_dict.get("auth_conf_cxt")
    polkit_pkla = test_dict.get("polkit_pkla")
    polkit_pkla_cxt = test_dict.get("polkit_pkla_cxt")
    ssh_setup = test_dict.get("ssh_setup", "no")
    tcp_setup = test_dict.get("tcp_setup", "no")
    tls_setup = test_dict.get("tls_setup", "no")
    unix_setup = test_dict.get("unix_setup", "no")
    ssh_recovery = test_dict.get("ssh_auto_recovery", "yes")
    tcp_recovery = test_dict.get("tcp_auto_recovery", "yes")
    tls_recovery = test_dict.get("tls_auto_recovery", "yes")
    unix_recovery = test_dict.get("unix_auto_recovery", "yes")
    sasl_allowed_username_list = test_dict.get("sasl_allowed_username_list")
    auth_unix_rw = test_dict.get("auth_unix_rw")
    kinit_pwd = test_dict.get("kinit_pwd")
    test_alias = test_dict.get("test_alias")

    config_list = []
    port = ""
    # extra URI arguments
    extra_params = ""
    # it's used to clean up SSH, TLS, TCP, UNIX and SASL objs later
    objs_list = []
    # redirect LIBVIRT_DEBUG log into test log later
    test_dict["logfile"] = test.logfile

    # Make sure all of parameters are assigned a valid value
    check_parameters(test_dict, test)
    # Make sure libvirtd on remote is running
    server_session = remote.wait_for_login('ssh', server_ip, '22',
                                           server_user, server_pwd,
                                           r"[\#\$]\s*$")

    remote_libvirtd = Libvirtd(session=server_session)
    if not remote_libvirtd.is_running():
        logging.debug("start libvirt on remote")
        res = remote_libvirtd.start()
        if not res:
            status, output = server_session.cmd_status_output("journalctl -xe")
            test.error("Failed to start libvirtd on remote. [status]: %s "
                       "[output]: %s." % (status, output))
    server_session.close()

    if distro.detect().name == 'rhel' and int(distro.detect().version) >= 9:
        # Update crypto policies to legacy for RHEL>=9 per Bug 1931723 or
        # https://libguestfs.org/virt-v2v-input-xen.1.html#ssh-authentication
        crypto_policies = process.run("update-crypto-policies --set LEGACY",
                                      ignore_status=False)

    # only simply connect libvirt daemon then return
    if no_any_config == "yes":
        test_dict["uri"] = "%s%s%s://%s" % (driver, plus, transport, uri_path)
        remote_access(test_dict, test)
        return

    # append extra 'pkipath' argument to URI if exists
    if custom_pki_path:
        extra_params = "?pkipath=%s" % custom_pki_path

    # append extra 'no_verify' argument to URI if exists
    if no_verify == "yes":
        extra_params = "?no_verify=1"

    # append extra 'socket' argument to URI if exists
    if unix_sock_dir:
        extra_params = "?socket=%s/libvirt-sock" % unix_sock_dir

    # generate auth.conf and default under the '/etc/libvirt'
    if auth_conf_cxt and auth_conf:
        cmd = "echo -e '%s' > %s" % (auth_conf_cxt, auth_conf)
        process.system(cmd, ignore_status=True, shell=True)

    # generate polkit_pkla and default under the
    # '/etc/polkit-1/localauthority/50-local.d/'
    if polkit_pkla_cxt and polkit_pkla:
        cmd = "echo -e '%s' > %s" % (polkit_pkla_cxt, polkit_pkla)
        process.system(cmd, ignore_status=True, shell=True)

    # generate remote IP
    if config_ipv6 == "yes" and ipv6_addr_des:
        remote_ip = "[%s]" % ipv6_addr_des
    elif config_ipv6 != "yes" and server_cn:
        remote_ip = server_cn
    elif config_ipv6 != "yes" and ipv6_addr_des:
        remote_ip = "[%s]" % ipv6_addr_des
    elif server_ip and transport != "unix":
        remote_ip = server_ip
    else:
        remote_ip = ""

    # get URI port
    if tcp_port != "":
        port = ":" + tcp_port

    if tls_port != "":
        port = ":" + tls_port

    if ssh_port != "" and not ipv6_addr_des:
        port = ":" + ssh_port

    # generate URI
    uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user,
                                   remote_ip, port, uri_path, extra_params)
    test_dict["uri"] = uri

    logging.debug("The final test dict:\n<%s>", test_dict)

    if virsh_cmd == "start" and transport != "unix":
        session = remote.wait_for_login("ssh", server_ip, "22", "root",
                                        server_pwd, "#")
        cmd = "virsh domstate %s" % vm_name
        status, output = session.cmd_status_output(cmd)
        if status:
            session.close()
            test.cancel(output)

        session.close()

    try:
        # setup IPv6
        if config_ipv6 == "yes":
            ipv6_obj = IPv6Manager(test_dict)
            objs_list.append(ipv6_obj)
            ipv6_obj.setup()

        # compare libvirt version if needs
        if diff_virt_ver == "yes":
            compare_virt_version(server_ip, server_user, server_pwd, test)

        # setup SSH
        if (transport == "ssh" or ssh_setup == "yes") and sasl_type != "plain":
            if not test_dict.get("auth_pwd"):
                ssh_obj = SSHConnection(test_dict)
                if ssh_recovery == "yes":
                    objs_list.append(ssh_obj)
                # setup test environment
                ssh_obj.conn_setup()
            else:
                # To access to server with password,
                # cleanup authorized_keys on remote
                ssh_pubkey_file = "/root/.ssh/id_rsa.pub"
                if (os.path.exists("/root/.ssh/id_rsa") and
                        os.path.exists(ssh_pubkey_file)):
                    remote_file_obj = remote.RemoteFile(address=server_ip,
                                                        client='scp',
                                                        username=server_user,
                                                        password=server_pwd,
                                                        port='22',
                                                        remote_path="/root/.ssh/authorized_keys")
                    with open(ssh_pubkey_file, 'r') as fd:
                        line = fd.read().split()[-1].rstrip('\n')
                    line = ".*" + line
                    remote_file_obj.remove([line])
                    objs_list.append(remote_file_obj)

        # setup TLS
        if transport == "tls" or tls_setup == "yes":
            tls_obj = TLSConnection(test_dict)
            if tls_recovery == "yes":
                objs_list.append(tls_obj)
            # reserve cert path
            tmp_dir = tls_obj.tmp_dir
            # setup test environment
            tls_obj.conn_setup()

        # setup TCP
        if transport == "tcp" or tcp_setup == "yes":
            tcp_obj = TCPConnection(test_dict)
            if tcp_recovery == "yes":
                objs_list.append(tcp_obj)
            # setup test environment
            tcp_obj.conn_setup()

        # create a directory if needs
        if mkdir_cmd:
            process.system(mkdir_cmd, ignore_status=True, shell=True)

        # setup UNIX
        if transport == "unix" or unix_setup == "yes" or sasl_type == "plain":
            unix_obj = UNIXConnection(test_dict)
            if unix_recovery == "yes":
                objs_list.append(unix_obj)
            # setup test environment
            unix_obj.conn_setup()

        # need to restart libvirt service for negative testing
        if restart_libvirtd == "no":
            remotely_control_libvirtd(server_ip, server_user,
                                      server_pwd, action, status_error)
        # check TCP/IP listening by service
        if restart_libvirtd != "no" and transport != "unix":
            service = 'libvirtd'
            if transport == "ssh":
                service = 'ssh'

            check_listening_port_remote_by_service(server_ip, server_user,
                                                   server_pwd, service,
                                                   port, listen_addr)

        # open the tls/tcp listening port on server
        if transport in ["tls", "tcp"]:
            firewalld_port = port[1:]
            server_session = remote.wait_for_login('ssh', server_ip, '22',
                                                   server_user, server_pwd,
                                                   r"[\#\$]\s*$")
            firewall_cmd = utils_iptables.Firewall_cmd(server_session)
            firewall_cmd.add_port(firewalld_port, 'tcp', permanent=True)
            server_session.close()

        if 'inv_transport' in test_dict:
            transport = test_dict['inv_transport']
            uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user,
                                           remote_ip, port, uri_path,
                                           extra_params)
            test_dict["uri"] = uri

        config_list = []
        if uri_aliases:
            uri_config = change_libvirtconf_on_client(
                {'uri_aliases': uri_aliases})
            config_list.append(uri_config)
            test_dict["uri"] = test_alias

        if uri_default:
            test_dict["uri"] = ""
            # Delete the default URI environment variable to prevent overriding
            del os.environ['LIBVIRT_DEFAULT_URI']
            uri_config = change_libvirtconf_on_client(
                {'uri_default': uri_default})
            config_list.append(uri_config)
            ret = virsh.command('uri', debug=True)
            if uri_default.strip('"') in ret.stdout_text:
                logging.debug("Virsh output as expected.")
            else:
                test.fail("Expected virsh output: {} not found in:{}".format(
                    uri_default.strip('"'), ret.stdout_text))

        # remove client certifications if exist, only for TLS negative testing
        if rm_client_key_cmd:
            process.system(rm_client_key_cmd, ignore_status=True, shell=True)

        if rm_client_cert_cmd:
            process.system(rm_client_cert_cmd, ignore_status=True, shell=True)

        # add user to specific group
        if adduser_cmd:
            process.system(adduser_cmd, ignore_status=True, shell=True)

        # change /etc/pki/libvirt/servercert.pem then
        # restart libvirt service on the remote host
        if tls_sanity_cert == "no" and ca_cn_new:
            test_dict['ca_cn'] = ca_cn_new
            test_dict['scp_new_cacert'] = 'no'
            tls_obj_new = TLSConnection(test_dict)
            test_dict['tls_obj_new'] = tls_obj_new
            # only setup new CA and server
            tls_obj_new.conn_setup(True, False)

        # obtain and cache a ticket
        if kinit_pwd and sasl_type == 'gssapi' and auth_unix_rw == 'sasl':
            username_list = json.loads(sasl_allowed_username_list)
            for username in username_list:
                kinit_cmd = "echo '%s' | kinit %s" % (kinit_pwd, username)
                process.system(kinit_cmd, ignore_status=True, shell=True)

        # setup SASL certification
        # From libvirt-3.2.0, the default sasl change from
        # DIGEST-MD5 to GSSAPI. "sasl_user" is discarded.
        # More details: https://libvirt.org/auth.html#ACL_server_kerberos
        if sasl_user_pwd and sasl_type in ['digest-md5', 'plain']:
            # covert string tuple and list to python data type
            sasl_user_pwd = eval(sasl_user_pwd)
            if sasl_allowed_users:
                sasl_allowed_users = eval(sasl_allowed_users)

            # create a sasl user
            sasl_obj = SASL(test_dict)
            objs_list.append(sasl_obj)
            sasl_obj.setup()

            for sasl_user, sasl_pwd in sasl_user_pwd:
                # need't authentication if the auth.conf is configured by user
                if not auth_conf:
                    if sasl_type == 'plain':
                        test_dict["auth_pwd"] = server_pwd
                        pass
                    else:
                        test_dict["auth_user"] = sasl_user
                        test_dict["auth_pwd"] = sasl_pwd
                    logging.debug("sasl_user, sasl_pwd = "
                                  "(%s, %s)", sasl_user, sasl_pwd)

                if sasl_allowed_users and sasl_user not in sasl_allowed_users:
                    test_dict["status_error"] = "yes"
                patterns_extra_dict = {"authentication name": sasl_user,
                                       "enter your password": sasl_pwd}
                test_dict["patterns_extra_dict"] = patterns_extra_dict
                remote_access(test_dict, test)
        else:
            if not uri_default:
                remote_access(test_dict, test)

    finally:
        # recovery test environment
        # Destroy the VM after all test are done
        for config in config_list:
            restore_libvirtconf_on_client(config)
        cleanup(objs_list)

        if vm_name:
            vm = env.get_vm(vm_name)
            if vm and vm.is_alive():
                vm.destroy(gracefully=False)

        if transport in ["tcp", "tls"] and 'firewalld_port' in locals():
            server_session = remote.wait_for_login('ssh', server_ip, '22',
                                                   server_user, server_pwd,
                                                   r"[\#\$]\s*$")
            firewall_cmd = utils_iptables.Firewall_cmd(server_session)
            firewall_cmd.remove_port(firewalld_port, 'tcp', permanent=True)
            server_session.close()

        if rmdir_cmd:
            process.system(rmdir_cmd, ignore_status=True, shell=True)

        if deluser_cmd:
            process.system(deluser_cmd, ignore_status=True, shell=True)

        if auth_conf and os.path.isfile(auth_conf):
            os.unlink(auth_conf)

        if polkit_pkla and os.path.isfile(polkit_pkla):
            os.unlink(polkit_pkla)
Beispiel #4
0
class NFSClient(object):

    """
    NFSClient class for handle nfs remotely mount and umount.
    """

    def __init__(self, params):
        # Setup SSH connection
        self.ssh_obj = SSHConnection(params)
        self.ssh_obj.conn_setup()

        self.mkdir_mount_remote = False
        self.mount_dir = params.get("nfs_mount_dir")
        self.mount_options = params.get("nfs_mount_options")
        self.mount_src = params.get("nfs_mount_src")
        self.nfs_client_ip = params.get("nfs_client_ip")
        self.nfs_server_ip = params.get("nfs_server_ip")
        self.ssh_user = params.get("ssh_username", "root")
        self.remote_nfs_mount = params.get("remote_nfs_mount", "yes")

    def is_mounted(self):
        """
        Check the NFS is mounted or not.

        :return: If the src is mounted as expect
        :rtype: Boolean
        """
        ssh_cmd = "ssh %s@%s " % (self.ssh_user, self.nfs_client_ip)
        find_mountpoint_cmd = "mount | grep -E '.*%s.*%s.*'" % (self.mount_src,
                                                                self.mount_dir)
        cmd = ssh_cmd + "'%s'" % find_mountpoint_cmd
        logging.debug("The command: %s", cmd)
        status, output = commands.getstatusoutput(cmd)
        if status:
            logging.debug("The command result: <%s:%s>", status, output)
            return False

        return True

    def setup(self):
        """
        Setup NFS client.
        """
        # Mount sharing directory to local host
        # it has been covered by class Nfs

        # Mount sharing directory to remote host
        if self.remote_nfs_mount == "yes":
            self.setup_remote()

    def cleanup(self):
        """
        Cleanup NFS client.
        """
        ssh_cmd = "ssh %s@%s " % (self.ssh_user, self.nfs_client_ip)
        logging.debug("Umount %s from %s" % (self.mount_dir, self.nfs_server_ip))
        umount_cmd = ssh_cmd + "'umount -l %s'" % self.mount_dir
        try:
            utils.system(umount_cmd, verbose=True)
        except error.CmdError:
            raise error.TestFail("Failed to run: %s", umount_cmd)

        if self.mkdir_mount_remote:
            rmdir_cmd = ssh_cmd + "'rm -rf %s'" % self.mount_dir
            try:
                utils.system(rmdir_cmd, verbose=True)
            except error.CmdError:
                raise error.TestFail("Failed to run: %s", rmdir_cmd)

        if self.is_mounted():
            raise error.TestFail("Failed to umount %s", self.mount_dir)

        # Recover SSH connection
        self.ssh_obj.auto_recover = True
        del self.ssh_obj

    def setup_remote(self):
        """
        Mount sharing directory to remote host.
        """
        ssh_cmd = "ssh %s@%s " % (self.ssh_user, self.nfs_client_ip)
        check_mount_dir_cmd = ssh_cmd + "'ls -d %s'" % self.mount_dir
        logging.debug("To check if the %s exists", self.mount_dir)
        output = commands.getoutput(check_mount_dir_cmd)
        if re.findall("No such file or directory", output, re.M):
            mkdir_cmd = ssh_cmd + "'mkdir -p %s'" % self.mount_dir
            logging.debug("Prepare to create %s", self.mount_dir)
            s, o = commands.getstatusoutput(mkdir_cmd)
            if s != 0:
                raise error.TestFail("Failed to run %s: %s", mkdir_cmd, o)
            self.mkdir_mount_remote = True

        self.mount_src = "%s:%s" % (self.nfs_server_ip, self.mount_src)
        logging.debug("Mount %s to %s" % (self.mount_src, self.mount_dir))
        mount_cmd = ssh_cmd + "'mount -t nfs %s %s -o %s'" % (self.mount_src,
                                                              self.mount_dir,
                                                              self.mount_options)
        try:
            utils.system(mount_cmd, verbose=True)
        except error.CmdError:
            raise error.TestFail("Failed to run: %s", mount_cmd)

        # Check if the sharing directory is mounted
        if not self.is_mounted():
            raise error.TestFail("Failed to mount from %s to %s",
                                 self.mount_src, self.mount_dir)
Beispiel #5
0
class NFSClient(object):
    """
    NFSClient class for handle nfs remotely mount and umount.
    """
    def __init__(self, params):
        # Setup SSH connection
        self.ssh_obj = SSHConnection(params)
        self.ssh_obj.conn_setup()

        self.mkdir_mount_remote = False
        self.mount_dir = params.get("nfs_mount_dir")
        self.mount_options = params.get("nfs_mount_options")
        self.mount_src = params.get("nfs_mount_src")
        self.nfs_client_ip = params.get("nfs_client_ip")
        self.nfs_server_ip = params.get("nfs_server_ip")
        self.ssh_user = params.get("ssh_username", "root")
        self.remote_nfs_mount = params.get("remote_nfs_mount", "yes")

    def is_mounted(self):
        """
        Check the NFS is mounted or not.

        :return: If the src is mounted as expect
        :rtype: Boolean
        """
        ssh_cmd = "ssh %s@%s " % (self.ssh_user, self.nfs_client_ip)
        find_mountpoint_cmd = "mount | grep -E '.*%s.*%s.*'" % (self.mount_src,
                                                                self.mount_dir)
        cmd = ssh_cmd + "'%s'" % find_mountpoint_cmd
        logging.debug("The command: %s", cmd)
        status, output = commands.getstatusoutput(cmd)
        if status:
            logging.debug("The command result: <%s:%s>", status, output)
            return False

        return True

    def setup(self):
        """
        Setup NFS client.
        """
        # Mount sharing directory to local host
        # it has been covered by class Nfs

        # Mount sharing directory to remote host
        if self.remote_nfs_mount == "yes":
            self.setup_remote()

    def cleanup(self):
        """
        Cleanup NFS client.
        """
        ssh_cmd = "ssh %s@%s " % (self.ssh_user, self.nfs_client_ip)
        logging.debug("Umount %s from %s" %
                      (self.mount_dir, self.nfs_server_ip))
        umount_cmd = ssh_cmd + "'umount -l %s'" % self.mount_dir
        try:
            utils.system(umount_cmd, verbose=True)
        except error.CmdError:
            raise error.TestFail("Failed to run: %s", umount_cmd)

        if self.mkdir_mount_remote:
            rmdir_cmd = ssh_cmd + "'rm -rf %s'" % self.mount_dir
            try:
                utils.system(rmdir_cmd, verbose=True)
            except error.CmdError:
                raise error.TestFail("Failed to run: %s", rmdir_cmd)

        if self.is_mounted():
            raise error.TestFail("Failed to umount %s", self.mount_dir)

        # Recover SSH connection
        self.ssh_obj.auto_recover = True
        del self.ssh_obj

    def setup_remote(self):
        """
        Mount sharing directory to remote host.
        """
        ssh_cmd = "ssh %s@%s " % (self.ssh_user, self.nfs_client_ip)
        check_mount_dir_cmd = ssh_cmd + "'ls -d %s'" % self.mount_dir
        logging.debug("To check if the %s exists", self.mount_dir)
        output = commands.getoutput(check_mount_dir_cmd)
        if re.findall("No such file or directory", output, re.M):
            mkdir_cmd = ssh_cmd + "'mkdir -p %s'" % self.mount_dir
            logging.debug("Prepare to create %s", self.mount_dir)
            s, o = commands.getstatusoutput(mkdir_cmd)
            if s != 0:
                raise error.TestFail("Failed to run %s: %s", mkdir_cmd, o)
            self.mkdir_mount_remote = True

        self.mount_src = "%s:%s" % (self.nfs_server_ip, self.mount_src)
        logging.debug("Mount %s to %s" % (self.mount_src, self.mount_dir))
        mount_cmd = ssh_cmd + "'mount -t nfs %s %s -o %s'" % (
            self.mount_src, self.mount_dir, self.mount_options)
        try:
            utils.system(mount_cmd, verbose=True)
        except error.CmdError:
            raise error.TestFail("Failed to run: %s", mount_cmd)

        # Check if the sharing directory is mounted
        if not self.is_mounted():
            raise error.TestFail("Failed to mount from %s to %s",
                                 self.mount_src, self.mount_dir)
Beispiel #6
0
class NFSClient(object):

    """
    NFSClient class for handle nfs remotely mount and umount.
    """

    def __init__(self, params):
        self.nfs_client_ip = params.get("nfs_client_ip")
        # To Avoid host key verification failure
        ret = process.run("ssh-keygen -R %s" % self.nfs_client_ip,
                          ignore_status=True)
        stderr = results_stderr_52lts(ret)
        if ret.exit_status and "No such file or directory" not in stderr:
            raise exceptions.TestFail("Failed to update host key: %s" %
                                      stderr)
        # Setup SSH connection
        self.ssh_obj = SSHConnection(params)
        ssh_timeout = int(params.get("ssh_timeout", 10))
        self.ssh_obj.conn_setup(timeout=ssh_timeout)

        self.params = params
        self.mkdir_mount_remote = False
        self.mount_dir = params.get("nfs_mount_dir")
        self.mount_options = params.get("nfs_mount_options")
        self.mount_src = params.get("nfs_mount_src")
        self.nfs_server_ip = params.get("nfs_server_ip")
        self.ssh_user = params.get("ssh_username", "root")
        self.remote_nfs_mount = params.get("remote_nfs_mount", "yes")
        self.ssh_hostkey_check = params.get("ssh_hostkey_check", "no") == "yes"
        self.ssh_cmd = "ssh %s@%s " % (self.ssh_user, self.nfs_client_ip)
        if not self.ssh_hostkey_check:
            self.ssh_cmd += "-o StrictHostKeyChecking=no "

    def is_mounted(self):
        """
        Check the NFS is mounted or not.

        :return: If the src is mounted as expect
        :rtype: Boolean
        """
        find_mountpoint_cmd = "mount | grep -E '.*%s.*%s.*'" % (self.mount_src,
                                                                self.mount_dir)
        cmd = self.ssh_cmd + "'%s'" % find_mountpoint_cmd
        logging.debug("The command: %s", cmd)
        status, output = process.getstatusoutput(cmd)
        if status:
            logging.debug("The command result: <%s:%s>", status, output)
            return False
        return True

    def setup(self):
        """
        Setup NFS client.
        """
        # Mount sharing directory to local host
        # it has been covered by class Nfs

        # Mount sharing directory to remote host
        if self.remote_nfs_mount == "yes":
            # stale file mounted causes test to fail instead
            # unmount it and perform the setup
            if self.is_mounted():
                self.umount()
            self.setup_remote()

    def umount(self):
        """
        Unmount the mount directory in remote host
        """
        logging.debug("Umount %s from %s" %
                      (self.mount_dir, self.nfs_client_ip))
        umount_cmd = self.ssh_cmd + "'umount -l %s'" % self.mount_dir
        try:
            process.system(umount_cmd, verbose=True)
        except process.CmdError:
            raise exceptions.TestFail("Failed to run: %s" % umount_cmd)

    def cleanup(self, ssh_auto_recover=True):
        """
        Cleanup NFS client.
        """
        self.umount()
        if self.mkdir_mount_remote:
            rmdir_cmd = self.ssh_cmd + "'rm -rf %s'" % self.mount_dir
            try:
                process.system(rmdir_cmd, verbose=True)
            except process.CmdError:
                raise exceptions.TestFail("Failed to run: %s" % rmdir_cmd)

        if self.is_mounted():
            raise exceptions.TestFail("Failed to umount %s" % self.mount_dir)

        # Recover SSH connection
        self.ssh_obj.auto_recover = ssh_auto_recover
        del self.ssh_obj

    def firewall_to_permit_nfs(self):
        """
        Method to configure firewall to permit NFS to be mounted
        from remote host
        """
        # Check firewall in host permit nfs service to mount from remote server
        try:
            firewalld = service.Factory.create_service("firewalld")
            if not firewalld.status():
                firewalld.start()
            firewall_cmd = "firewall-cmd --list-all | grep services:"
            try:
                ret = process.run(firewall_cmd, shell=True)
                if not ret.exit_status:
                    firewall_services = results_stdout_52lts(ret).split(':')[1].strip().split(' ')
                    if 'nfs' not in firewall_services:
                        service_cmd = "firewall-cmd --permanent --zone=public "
                        service_cmd += "--add-service=nfs"
                        ret = process.run(service_cmd, shell=True)
                        if ret.exit_status:
                            logging.error("nfs service not added in firewall: "
                                          "%s", results_stdout_52lts(ret))
                        else:
                            logging.debug("nfs service added to firewall "
                                          "sucessfully")
                            firewalld.restart()
                    else:
                        logging.debug("nfs service already permitted by firewall")
            except process.CmdError:
                # For RHEL 6 based system firewall-cmd is not available
                logging.debug("Using iptables to permit NFS service")
                nfs_ports = []
                rule_list = []
                nfsd = service.Factory.create_service("nfs")
                rpcd = service.Factory.create_service("rpcbind")
                iptables = service.Factory.create_service("iptables")
                nfs_sysconfig = self.params.get("nfs_sysconfig_path",
                                                "/etc/sysconfig/nfs")
                tcp_port = self.params.get("nfs_tcp_port", "32803")
                udp_port = self.params.get("nfs_udp_port", "32769")
                mountd_port = self.params.get("nfs_mountd_port", "892")
                subnet_mask = self.params.get("priv_subnet", "192.168.2.0/24")
                nfs_ports.append("LOCKD_TCPPORT=%s" % tcp_port)
                nfs_ports.append("LOCKD_UDPPORT=%s" % udp_port)
                nfs_ports.append("MOUNTD_PORT=%s" % mountd_port)
                cmd_output = decode_to_text(process.system_output(
                    "cat %s" % nfs_sysconfig, shell=True))
                exist_ports = cmd_output.strip().split('\n')
                # check if the ports are already configured, if not then add it
                for each_port in nfs_ports:
                    if each_port not in exist_ports:
                        process.run("echo '%s' >> %s" %
                                    (each_port, nfs_sysconfig), shell=True)
                rpcd.restart()
                nfsd.restart()
                rule_temp = "INPUT -m state --state NEW -p %s -m multiport "
                rule_temp += "--dport 111,892,2049,%s -s %s -j ACCEPT"
                rule = rule_temp % ("tcp", tcp_port, subnet_mask)
                rule_list.append(rule)
                rule = rule_temp % ("udp", udp_port, subnet_mask)
                rule_list.append(rule)
                Iptables.setup_or_cleanup_iptables_rules(rule_list)
                iptables.restart()
        except Exception as info:
            logging.error("Firewall setting to add nfs service "
                          "failed: %s", info)

    def setup_remote(self):
        """
        Mount sharing directory to remote host.
        """
        check_mount_dir_cmd = self.ssh_cmd + "'ls -d %s'" % self.mount_dir
        logging.debug("To check if the %s exists", self.mount_dir)
        output = process.getoutput(check_mount_dir_cmd)
        if re.findall("No such file or directory", output, re.M):
            mkdir_cmd = self.ssh_cmd + "'mkdir -p %s'" % self.mount_dir
            logging.debug("Prepare to create %s", self.mount_dir)
            s, o = process.getstatusoutput(mkdir_cmd)
            if s != 0:
                raise exceptions.TestFail("Failed to run %s: %s" %
                                          (mkdir_cmd, o))
            self.mkdir_mount_remote = True

        if self.params.get("firewall_to_permit_nfs", "yes") == "yes":
            self.firewall_to_permit_nfs()

        self.mount_src = "%s:%s" % (self.nfs_server_ip, self.mount_src)
        logging.debug("Mount %s to %s" % (self.mount_src, self.mount_dir))
        mount_cmd = "mount -t nfs %s %s" % (self.mount_src, self.mount_dir)
        if self.mount_options:
            mount_cmd += " -o %s" % self.mount_options
        try:
            cmd = "%s '%s'" % (self.ssh_cmd, mount_cmd)
            process.system(cmd, verbose=True)
        except process.CmdError:
            raise exceptions.TestFail("Failed to run: %s" % cmd)

        # Check if the sharing directory is mounted
        if not self.is_mounted():
            raise exceptions.TestFail("Failed to mount from %s to %s" %
                                      self.mount_src, self.mount_dir)
def run(test, params, env):
    """
    Test remote access with TCP, TLS connection
    """

    test_dict = dict(params)
    vm_name = test_dict.get("main_vm")
    status_error = test_dict.get("status_error", "no")
    allowed_dn_str = params.get("tls_allowed_dn_list")
    if allowed_dn_str:
        allowed_dn_list = []
        if not libvirt_version.version_compare(1, 0, 0):
            # Reverse the order in the dn list to workaround the
            # feature changes between RHEL 6 and RHEL 7
            dn_list = allowed_dn_str.split(",")
            dn_list.reverse()
            allowed_dn_str = ','.join(dn_list)
        allowed_dn_list.append(allowed_dn_str)
        test_dict['tls_allowed_dn_list'] = allowed_dn_list
    transport = test_dict.get("transport")
    plus = test_dict.get("conn_plus", "+")
    config_ipv6 = test_dict.get("config_ipv6", "no")
    tls_port = test_dict.get("tls_port", "")
    listen_addr = test_dict.get("listen_addr", "0.0.0.0")
    ssh_port = test_dict.get("ssh_port", "")
    tcp_port = test_dict.get("tcp_port", "")
    server_ip = test_dict.get("server_ip")
    server_user = test_dict.get("server_user")
    server_pwd = test_dict.get("server_pwd")
    no_any_config = params.get("no_any_config", "no")
    sasl_type = test_dict.get("sasl_type", "gssapi")
    sasl_user_pwd = test_dict.get("sasl_user_pwd")
    sasl_allowed_users = test_dict.get("sasl_allowed_users")
    server_cn = test_dict.get("server_cn")
    custom_pki_path = test_dict.get("custom_pki_path")
    rm_client_key_cmd = test_dict.get("remove_client_key_cmd")
    rm_client_cert_cmd = test_dict.get("remove_client_cert_cmd")
    ca_cn_new = test_dict.get("ca_cn_new")
    no_verify = test_dict.get("no_verify", "no")
    ipv6_addr_des = test_dict.get("ipv6_addr_des")
    tls_sanity_cert = test_dict.get("tls_sanity_cert")
    restart_libvirtd = test_dict.get("restart_libvirtd", "yes")
    diff_virt_ver = test_dict.get("diff_virt_ver", "no")
    driver = test_dict.get("test_driver", "qemu")
    uri_path = test_dict.get("uri_path", "/system")
    virsh_cmd = params.get("virsh_cmd", "list")
    action = test_dict.get("libvirtd_action", "restart")
    uri_user = test_dict.get("uri_user", "")
    unix_sock_dir = test_dict.get("unix_sock_dir")
    mkdir_cmd = test_dict.get("mkdir_cmd")
    rmdir_cmd = test_dict.get("rmdir_cmd")
    adduser_cmd = test_dict.get("adduser_cmd")
    deluser_cmd = test_dict.get("deluser_cmd")
    auth_conf = test_dict.get("auth_conf")
    auth_conf_cxt = test_dict.get("auth_conf_cxt")
    polkit_pkla = test_dict.get("polkit_pkla")
    polkit_pkla_cxt = test_dict.get("polkit_pkla_cxt")
    ssh_setup = test_dict.get("ssh_setup", "no")
    tcp_setup = test_dict.get("tcp_setup", "no")
    tls_setup = test_dict.get("tls_setup", "no")
    unix_setup = test_dict.get("unix_setup", "no")
    ssh_recovery = test_dict.get("ssh_auto_recovery", "yes")
    tcp_recovery = test_dict.get("tcp_auto_recovery", "yes")
    tls_recovery = test_dict.get("tls_auto_recovery", "yes")
    unix_recovery = test_dict.get("unix_auto_recovery", "yes")

    port = ""
    # extra URI arguments
    extra_params = ""
    # it's used to clean up SSH, TLS, TCP, UNIX and SASL objs later
    objs_list = []
    # redirect LIBVIRT_DEBUG log into test log later
    test_dict["logfile"] = test.logfile

    # Make sure all of parameters are assigned a valid value
    check_parameters(test_dict, test)

    # only simply connect libvirt daemon then return
    if no_any_config == "yes":
        test_dict["uri"] = "%s%s%s://%s" % (driver, plus, transport, uri_path)
        remote_access(test_dict, test)
        return

    # append extra 'pkipath' argument to URI if exists
    if custom_pki_path:
        extra_params = "?pkipath=%s" % custom_pki_path

    # append extra 'no_verify' argument to URI if exists
    if no_verify == "yes":
        extra_params = "?no_verify=1"

    # append extra 'socket' argument to URI if exists
    if unix_sock_dir:
        extra_params = "?socket=%s/libvirt-sock" % unix_sock_dir

    # generate auth.conf and default under the '/etc/libvirt'
    if auth_conf_cxt and auth_conf:
        cmd = "echo -e '%s' > %s" % (auth_conf_cxt, auth_conf)
        process.system(cmd, ignore_status=True, shell=True)

    # generate polkit_pkla and default under the
    # '/etc/polkit-1/localauthority/50-local.d/'
    if polkit_pkla_cxt and polkit_pkla:
        cmd = "echo -e '%s' > %s" % (polkit_pkla_cxt, polkit_pkla)
        process.system(cmd, ignore_status=True, shell=True)

    # generate remote IP
    if config_ipv6 == "yes" and ipv6_addr_des:
        remote_ip = "[%s]" % ipv6_addr_des
    elif config_ipv6 != "yes" and server_cn:
        remote_ip = server_cn
    elif config_ipv6 != "yes" and ipv6_addr_des:
        remote_ip = "[%s]" % ipv6_addr_des
    elif server_ip and transport != "unix":
        remote_ip = server_ip
    else:
        remote_ip = ""

    # get URI port
    if tcp_port != "":
        port = ":" + tcp_port

    if tls_port != "":
        port = ":" + tls_port

    if ssh_port != "" and not ipv6_addr_des:
        port = ":" + ssh_port

    # generate URI
    uri = "%s%s%s://%s%s%s%s%s" % (driver, plus, transport, uri_user,
                                   remote_ip, port, uri_path, extra_params)
    test_dict["uri"] = uri

    logging.debug("The final test dict:\n<%s>", test_dict)

    if virsh_cmd == "start" and transport != "unix":
        session = remote.wait_for_login("ssh", server_ip, "22", "root",
                                        server_pwd, "#")
        cmd = "virsh domstate %s" % vm_name
        status, output = session.cmd_status_output(cmd)
        if status:
            session.close()
            test.cancel(output)

        session.close()

    try:
        # setup IPv6
        if config_ipv6 == "yes":
            ipv6_obj = IPv6Manager(test_dict)
            objs_list.append(ipv6_obj)
            ipv6_obj.setup()

        # compare libvirt version if needs
        if diff_virt_ver == "yes":
            compare_virt_version(server_ip, server_user, server_pwd, test)

        # setup SSH
        if transport == "ssh" or ssh_setup == "yes":
            if not test_dict.get("auth_pwd"):
                ssh_obj = SSHConnection(test_dict)
                if ssh_recovery == "yes":
                    objs_list.append(ssh_obj)
                # setup test environment
                ssh_obj.conn_setup()

        # setup TLS
        if transport == "tls" or tls_setup == "yes":
            tls_obj = TLSConnection(test_dict)
            if tls_recovery == "yes":
                objs_list.append(tls_obj)
            # reserve cert path
            tmp_dir = tls_obj.tmp_dir
            # setup test environment
            if tls_sanity_cert == "no":
                # only setup CA and client
                tls_obj.conn_setup(False, True)
            else:
                # setup CA, server and client
                tls_obj.conn_setup()

        # setup TCP
        if transport == "tcp" or tcp_setup == "yes":
            tcp_obj = TCPConnection(test_dict)
            if tcp_recovery == "yes":
                objs_list.append(tcp_obj)
            # setup test environment
            tcp_obj.conn_setup()

        # create a directory if needs
        if mkdir_cmd:
            process.system(mkdir_cmd, ignore_status=True, shell=True)

        # setup UNIX
        if transport == "unix" or unix_setup == "yes":
            unix_obj = UNIXConnection(test_dict)
            if unix_recovery == "yes":
                objs_list.append(unix_obj)
            # setup test environment
            unix_obj.conn_setup()

        # need to restart libvirt service for negative testing
        if restart_libvirtd == "no":
            remotely_control_libvirtd(server_ip, server_user,
                                      server_pwd, action, status_error)

        # check TCP/IP listening by service
        if restart_libvirtd != "no" and transport != "unix":
            service = 'libvirtd'
            if transport == "ssh":
                service = 'ssh'

            check_listening_port_remote_by_service(server_ip, server_user,
                                                   server_pwd, service,
                                                   port, listen_addr)

        # remove client certifications if exist, only for TLS negative testing
        if rm_client_key_cmd:
            process.system(rm_client_key_cmd, ignore_status=True, shell=True)

        if rm_client_cert_cmd:
            process.system(rm_client_cert_cmd, ignore_status=True, shell=True)

        # add user to specific group
        if adduser_cmd:
            process.system(adduser_cmd, ignore_status=True, shell=True)

        # change /etc/pki/libvirt/servercert.pem then
        # restart libvirt service on the remote host
        if tls_sanity_cert == "no" and ca_cn_new:
            test_dict['ca_cn'] = ca_cn_new
            test_dict['ca_cakey_path'] = tmp_dir
            test_dict['scp_new_cacert'] = 'no'
            tls_obj_new = TLSConnection(test_dict)
            test_dict['tls_obj_new'] = tls_obj_new
            # only setup new CA and server
            tls_obj_new.conn_setup(True, False)

        # setup SASL certification
        # From libvirt-3.2.0, the default sasl change from
        # DIGEST-MD5 to GSSAPI. "sasl_user" is discarded.
        # More details: https://libvirt.org/auth.html#ACL_server_kerberos
        if sasl_user_pwd and sasl_type == 'digest-md5':
            # covert string tuple and list to python data type
            sasl_user_pwd = eval(sasl_user_pwd)
            if sasl_allowed_users:
                sasl_allowed_users = eval(sasl_allowed_users)

            # create a sasl user
            sasl_obj = SASL(test_dict)
            objs_list.append(sasl_obj)
            sasl_obj.setup()

            for sasl_user, sasl_pwd in sasl_user_pwd:
                # need't authentication if the auth.conf is configured by user
                if not auth_conf:
                    test_dict["auth_user"] = sasl_user
                    test_dict["auth_pwd"] = sasl_pwd
                    logging.debug("sasl_user, sasl_pwd = "
                                  "(%s, %s)", sasl_user, sasl_pwd)

                if sasl_allowed_users and sasl_user not in sasl_allowed_users:
                    test_dict["status_error"] = "yes"
                patterns_extra_dict = {"authentication name": sasl_user}
                test_dict["patterns_extra_dict"] = patterns_extra_dict
                remote_access(test_dict, test)
        else:
            remote_access(test_dict, test)

    finally:
        # recovery test environment
        # Destroy the VM after all test are done
        cleanup(objs_list)

        if vm_name:
            vm = env.get_vm(vm_name)
            if vm and vm.is_alive():
                vm.destroy(gracefully=False)

        if rmdir_cmd:
            process.system(rmdir_cmd, ignore_status=True, shell=True)

        if deluser_cmd:
            process.system(deluser_cmd, ignore_status=True, shell=True)

        if auth_conf and os.path.isfile(auth_conf):
            os.unlink(auth_conf)

        if polkit_pkla and os.path.isfile(polkit_pkla):
            os.unlink(polkit_pkla)