예제 #1
0
def run(test, params, env):
    """
    Test Step:
        1. Boot up two virtual machine
        2. Set openflow rules
        3. Run ping test, nc(tcp, udp) test, check whether openflow rules take
           effect.
    Params:
        :param test: QEMU test object
        :param params: Dictionary with the test parameters
        :param env: Dictionary with test environment.
    """
    def run_tcpdump_bg(vm, addresses, dump_protocol):
        """
        Run tcpdump in background, tcpdump will exit once catch a packet
        match the rules.
        """
        bg_session = vm.wait_for_login()
        if tcpdump_is_alive(bg_session):
            bg_session.cmd("killall -9 tcpdump")
        tcpdump_cmd = ("setsid tcpdump -iany -n -v %s and 'src %s and dst %s'"
                       " -c 1 >/dev/null 2>&1")
        bg_session.sendline(tcpdump_cmd % (dump_protocol, addresses[0],
                                           addresses[1]))
        if not utils_misc.wait_for(lambda: tcpdump_is_alive(bg_session),
                                   30, 0, 1, "Waiting tcpdump start..."):
            test.cancel("Error, can not run tcpdump")
        bg_session.close()

    def dump_catch_data(session, dump_log, catch_reg):
        """
        Search data from dump_log
        """
        dump_info = session.cmd_output("cat %s" % dump_log)
        if re.findall(catch_reg, dump_info, re.I):
            return True
        return False

    def tcpdump_is_alive(session):
        """
        Check whether tcpdump is alive
        """
        if session.cmd_status("pidof tcpdump"):
            return False
        return True

    def tcpdump_catch_packet_test(session, drop_flow=False):
        """
        Check whether tcpdump catch match rules packets, once catch a packet
        match rules tcpdump will exit.
        when drop_flow is 'True', tcpdump couldn't catch any packets.
        """
        packet_receive = not tcpdump_is_alive(session)
        if packet_receive == drop_flow:
            err_msg = "Error, flow %s" % (drop_flow and "was" or "wasn't")
            err_msg += " dropped, tcpdump "
            err_msg += "%s " % (packet_receive and "can" or "can not")
            err_msg += "receive the packets"
            test.error(err_msg)
        logging.info("Correct, flow %s dropped, tcpdump %s receive the packet"
                     % ((drop_flow and "was" or "was not"),
                         (packet_receive and "can" or "can not")))

    def arp_entry_clean(entry=None):
        """
        Clean arp catch in guest
        """
        if not entry:
            arp_clean_cmd = "arp -n | awk '/^[1-2]/{print \"arp -d \" $1}'|sh"
        else:
            arp_clean_cmd = "arp -d %s" % entry
        for session in sessions:
            session.cmd_output_safe(arp_clean_cmd)

    def check_arp_info(session, entry, vm, match_mac=None):
        arp_info = session.cmd_output("arp -n")
        arp_entries = [_ for _ in arp_info.splitlines() if re.match(entry, _)]

        match_string = match_mac or "incomplete"

        if not arp_entries:
            test.error("Can not find arp entry in %s: %s"
                       % (vm.name, arp_info))

        if not re.findall(match_string, arp_entries[0], re.I):
            test.fail("Can not find the mac address"
                      " %s of %s in arp"
                      " entry %s" % (match_mac, vm.name, arp_entries[0]))

    def ping_test(session, dst, drop_flow=False):
        """
        Ping test, check icmp
        """
        ping_status, ping_output = utils_test.ping(dest=dst, count=10,
                                                   timeout=20, session=session)
        # when drop_flow is true, ping should failed(return not zero)
        # drop_flow is false, ping should success
        packets_lost = 100
        if ping_status and not drop_flow:
            test.error("Ping should success when not drop_icmp")
        elif not ping_status:
            packets_lost = utils_test.get_loss_ratio(ping_output)
            if drop_flow and packets_lost != 100:
                test.error("When drop_icmp, ping shouldn't works")
            if not drop_flow and packets_lost == 100:
                test.error("When not drop_icmp, ping should works")

        info_msg = "Correct, icmp flow %s dropped, ping '%s', "
        info_msg += "packets lost rate is: '%s'"
        logging.info(info_msg % ((drop_flow and "was" or "was not"),
                                 (ping_status and "failed" or "success"),
                                 packets_lost))

    def run_ping_bg(vm, dst):
        """
        Run ping in background
        """
        ping_cmd = "ping %s" % dst
        session = vm.wait_for_login()
        logging.info("Ping %s in background" % dst)
        session.sendline(ping_cmd)
        return session

    def check_bg_ping(session):
        ping_pattern = r"\d+ bytes from \d+.\d+.\d+.\d+:"
        ping_pattern += r" icmp_seq=\d+ ttl=\d+ time=.*? ms"
        ping_failed_pattern = r"From .*? icmp_seq=\d+ Destination"
        ping_failed_pattern += r" Host Unreachable"
        try:
            out = session.read_until_output_matches([ping_pattern,
                                                     ping_failed_pattern])
            if re.search(ping_failed_pattern, out[1]):
                return False, out[1]
            else:
                return True, out[1]
        except Exception as msg:
            return False, msg

    def file_transfer(sessions, addresses, timeout):
        prepare_cmd = "dd if=/dev/zero of=/tmp/copy_file count=1024 bs=1M"
        md5_cmd = "md5sum /tmp/copy_file"
        port = params.get("shell_port")
        prompt = params.get("shell_prompt")
        username = params.get("username")
        password = params.get("password")
        sessions[0].cmd(prepare_cmd, timeout=timeout)
        ori_md5 = sessions[0].cmd_output(md5_cmd)
        scp_cmd = (r"scp -v -o UserKnownHostsFile=/dev/null "
                   r"-o StrictHostKeyChecking=no "
                   r"-o PreferredAuthentications=password -r "
                   r"-P %s /tmp/copy_file %s@\[%s\]:/tmp/copy_file" %
                   (port, username, addresses[1]))
        sessions[0].sendline(scp_cmd)
        remote.handle_prompts(sessions[0], username, password, prompt, 600)
        new_md5 = sessions[1].cmd_output(md5_cmd)
        for session in sessions:
            session.cmd("rm -f /tmp/copy_file")
        if new_md5 != ori_md5:
            test.fail("Md5 value changed after file transfer, "
                      "original is %s and the new file"
                      " is: %s" % (ori_md5, new_md5))

    def nc_connect_test(sessions, addresses, drop_flow=False, nc_port="8899",
                        udp_model=False):
        """
        Nc connect test, check tcp and udp
        """
        nc_log = "/tmp/nc_log"
        server_cmd = "nc -l %s"
        client_cmd = "echo client | nc %s %s"
        if udp_model:
            server_cmd += " -u -w 3"
            client_cmd += " -u -w 3"
        server_cmd += " > %s &"
        client_cmd += " &"
        try:
            sessions[1].cmd_output_safe(server_cmd % (nc_port, nc_log))
            sessions[0].cmd_output_safe(client_cmd % (addresses[1], nc_port))

            nc_protocol = udp_model and "UDP" or "TCP"
            nc_connect = False
            if utils_misc.wait_for(
                    lambda: dump_catch_data(sessions[1], nc_log, "client"),
                    10, 0, 2, text="Wait '%s' connect" % nc_protocol):
                nc_connect = True
            if nc_connect == drop_flow:
                err_msg = "Error, '%s' " % nc_protocol
                err_msg += "flow %s " % (drop_flow and "was" or "was not")
                err_msg += "dropped, nc connect should"
                err_msg += " '%s'" % (nc_connect and "failed" or "success")
                test.error(err_msg)

            logging.info("Correct, '%s' flow %s dropped, and nc connect %s" %
                         (nc_protocol, (drop_flow and "was" or "was not"),
                          (nc_connect and "success" or "failed")))
        finally:
            for session in sessions:
                session.cmd_output_safe("killall nc || killall ncat")
                session.cmd("%s %s" % (clean_cmd, nc_log),
                            ignore_all_errors=True)

    def acl_rules_check(acl_rules, flow_options):
        flow_options = re.sub("action=", "actions=", flow_options)
        if "arp" in flow_options:
            flow_options = re.sub("nw_src=", "arp_spa=", flow_options)
            flow_options = re.sub("nw_dst=", "arp_tpa=", flow_options)
        acl_options = re.split(",", flow_options)
        for line in acl_rules.splitlines():
            rule = [_.lower() for _ in re.split("[ ,]", line) if _]
            item_in_rule = 0

            for acl_item in acl_options:
                if acl_item.lower() in rule:
                    item_in_rule += 1

            if item_in_rule == len(acl_options):
                return True
        return False

    def remove_plus_items(open_flow_rules):
        plus_items = ["duration", "n_packets", "n_bytes", "idle_age", "hard_age"]
        for plus_item in plus_items:
            open_flow_rules = re.sub("%s=.*?," % plus_item, "",
                                     open_flow_rules)
        return open_flow_rules

    br_name = params.get("netdst", "ovs0")
    timeout = int(params.get("login_timeout", '360'))
    prepare_timeout = int(params.get("prepare_timeout", '360'))
    clean_cmd = params.get("clean_cmd", "rm -f")
    sessions = []
    addresses = []
    vms = []
    bg_ping_session = None

    if not utils_net.ovs_br_exists(br_name):
        test.cancel("%s isn't an openvswith bridge" % br_name)

    error_context.context("Init boot the vms")
    for vm_name in params.objects("vms"):
        vms.append(env.get_vm(vm_name))
    for vm in vms:
        vm.verify_alive()
        sessions.append(vm.wait_for_login(timeout=timeout))
        addresses.append(vm.get_address())

    # set openflow rules:
    f_protocol = params.get("flow", "arp")
    f_base_options = "%s,nw_src=%s,nw_dst=%s" % (f_protocol, addresses[0],
                                                 addresses[1])
    for session in sessions:
        session.cmd("systemctl stop firewalld || service firewalld stop",
                    ignore_all_errors=True)

    try:
        for drop_flow in [True, False]:
            if drop_flow:
                f_command = "add-flow"
                f_options = f_base_options + ",action=drop"
                drop_icmp = eval(params.get("drop_icmp", 'True'))
                drop_tcp = eval(params.get("drop_tcp", 'True'))
                drop_udp = eval(params.get("drop_udp", 'True'))
            else:
                f_command = "mod-flows"
                f_options = f_base_options + ",action=normal"
                drop_icmp = False
                drop_tcp = False
                drop_udp = False

            error_context.base_context("Test prepare")
            error_context.context("Do %s %s on %s"
                                  % (f_command, f_options, br_name))
            utils_net.openflow_manager(br_name, f_command, f_options)
            acl_rules = utils_net.openflow_manager(
                br_name, "dump-flows").stdout.decode()
            if not acl_rules_check(acl_rules, f_options):
                test.fail("Can not find the rules from"
                          " ovs-ofctl: %s" % acl_rules)

            error_context.context("Run tcpdump in guest %s" % vms[1].name,
                                  logging.info)
            run_tcpdump_bg(vms[1], addresses, f_protocol)

            if drop_flow or f_protocol is not "arp":
                error_context.context("Clean arp cache in both guest",
                                      logging.info)
                arp_entry_clean(addresses[1])

            error_context.base_context(
                "Exec '%s' flow '%s' test" %
                (f_protocol, drop_flow and "drop" or "normal"))
            if drop_flow:
                error_context.context("Ping test form %s to %s" %
                                      (vms[0].name, vms[1].name), logging.info)
                ping_test(sessions[0], addresses[1], drop_icmp)
                if params.get("run_file_transfer") == "yes":
                    error_context.context("Transfer file form %s to %s" %
                                          (vms[0].name, vms[1].name),
                                          logging.info)
                    file_transfer(sessions, addresses, prepare_timeout)
            else:
                error_context.context("Ping test form %s to %s in background" %
                                      (vms[0].name, vms[1].name), logging.info)
                bg_ping_session = run_ping_bg(vms[0], addresses[1])

            if f_protocol == 'arp' and drop_flow:
                error_context.context("Check arp inside %s" % vms[0].name,
                                      logging.info)
                check_arp_info(sessions[0], addresses[1], vms[0])
            elif f_protocol == 'arp' or params.get("check_arp") == "yes":
                time.sleep(2)
                error_context.context("Check arp inside guests.", logging.info)
                for index, address in enumerate(addresses):
                    sess_index = (index + 1) % 2
                    mac = vms[index].virtnet.get_mac_address(0)
                    check_arp_info(sessions[sess_index], address, vms[index],
                                   mac)

            error_context.context("Run nc connect test via tcp", logging.info)
            nc_connect_test(sessions, addresses, drop_tcp)

            error_context.context("Run nc connect test via udp", logging.info)
            nc_connect_test(sessions, addresses, drop_udp, udp_model=True)

            error_context.context("Check tcpdump data catch", logging.info)
            tcpdump_catch_packet_test(sessions[1], drop_flow)
    finally:
        openflow_rules_ori = utils_net.openflow_manager(
            br_name, "dump-flows").stdout.decode()
        openflow_rules_ori = remove_plus_items(openflow_rules_ori)
        utils_net.openflow_manager(br_name, "del-flows", f_protocol)
        openflow_rules = utils_net.openflow_manager(
            br_name, "dump-flows").stdout.decode()
        openflow_rules = remove_plus_items(openflow_rules)
        removed_rule = list(set(openflow_rules_ori.splitlines()) -
                            set(openflow_rules.splitlines()))

        if f_protocol == "tcp":
            error_context.context("Run nc connect test via tcp", logging.info)
            nc_connect_test(sessions, addresses)
        elif f_protocol == "udp":
            error_context.context("Run nc connect test via udp", logging.info)
            nc_connect_test(sessions, addresses, udp_model=True)

        for session in sessions:
            session.close()
        failed_msg = []
        if (not removed_rule or
                not acl_rules_check(removed_rule[0], f_options)):
            failed_msg.append("Failed to delete %s" % f_options)
        if bg_ping_session:
            bg_ping_ok = check_bg_ping(bg_ping_session)
            bg_ping_session.close()
            if not bg_ping_ok[0]:
                failed_msg.append("There is something wrong happen in "
                                  "background ping: %s" % bg_ping_ok[1])

        if failed_msg:
            test.fail(failed_msg)
예제 #2
0
            if drop_flow:
                f_command = "add-flow"
                f_options = f_base_options + ",action=drop"
                drop_icmp = eval(params.get("drop_icmp", 'True'))
                drop_tcp = eval(params.get("drop_tcp", 'True'))
                drop_udp = eval(params.get("drop_udp", 'True'))
            else:
                f_command = "mod-flows"
                f_options = f_base_options + ",action=normal"
                drop_icmp = False
                drop_tcp = False
                drop_udp = False

            error.base_context("Test prepare")
            error.context("Do %s %s on %s" % (f_command, f_options, br_name))
            utils_net.openflow_manager(br_name, f_command, f_options)
            acl_rules = utils_net.openflow_manager(br_name, "dump-flows").stdout
            if not acl_rules_check(acl_rules, f_options):
                raise error.TestFail("Can not find the rules from"
                                     " ovs-ofctl: %s" % acl_rules)

            error.context("Run tcpdump in guest %s" % vms[1].name, logging.info)
            run_tcpdump_bg(sessions[1], addresses, f_protocol)

            if drop_flow or f_protocol is not "arp":
                error.context("Clean arp cache in both guest", logging.info)
                arp_entry_clean(addresses[1])

            error.base_context("Exec '%s' flow '%s' test" %
                               (f_protocol, drop_flow and "drop" or "normal"))
            if drop_flow:
예제 #3
0
def run(test, params, env):
    """
    Test Step:
        1. Boot up two virtual machine
        2. Set openflow rules
        3. Run ping test, nc(tcp, udp) test, check whether openflow rules take
           effect.
    Params:
        :param test: QEMU test object
        :param params: Dictionary with the test parameters
        :param env: Dictionary with test environment.
    """
    def run_tcpdump_bg(session, addresses, dump_protocol):
        """
        Run tcpdump in background, tcpdump will exit once catch a packet
        match the rules.
        """
        tcpdump_cmd = "killall -9 tcpdump; "
        tcpdump_cmd += "tcpdump -iany -n -v %s and 'src %s and dst %s' -c 1 &"
        session.cmd_output_safe(tcpdump_cmd %
                                (dump_protocol, addresses[0], addresses[1]))
        if not utils_misc.wait_for(lambda: tcpdump_is_alive(session), 30, 0, 1,
                                   "Waiting tcpdump start..."):
            raise error.TestNAError("Error, can not run tcpdump")

    def dump_catch_data(session, dump_log, catch_reg):
        """
        Search data from dump_log
        """
        dump_info = session.cmd_output("cat %s" % dump_log)
        if re.findall(catch_reg, dump_info, re.I):
            return True
        return False

    def tcpdump_is_alive(session):
        """
        Check whether tcpdump is alive
        """
        if session.cmd_status("pidof tcpdump"):
            return False
        return True

    def tcpdump_catch_packet_test(session, drop_flow=False):
        """
        Check whether tcpdump catch match rules packets, once catch a packet
        match rules tcpdump will exit.
        when drop_flow is 'True', tcpdump couldn't catch any packets.
        """
        packet_receive = not tcpdump_is_alive(session)
        if packet_receive == drop_flow:
            err_msg = "Error, flow %s dropped, tcpdump %s receive the packets"
            raise error.TestError(err_msg %
                                  ((drop_flow and "was" or "wasn't"),
                                   (packet_receive and "can" or "can not")))
        logging.info(
            "Correct, flow %s dropped, tcpdump %s receive the packet" %
            ((drop_flow and "was" or "was not"),
             (packet_receive and "can" or "can not")))

    def arp_entry_clean(session, entry=None):
        """
        Clean arp catch in guest
        """
        if not entry:
            arp_clean_cmd = "arp -n | awk '/^[1-2]/{print \"arp -d \" $1}'|sh"
        else:
            arp_clean_cmd = "arp -d %s" % entry
        for session in sessions:
            session.cmd_output_safe(arp_clean_cmd)

    def ping_test(session, dst, drop_flow=False):
        """
        Ping test, check icmp
        """
        ping_status, ping_output = utils_test.ping(dest=dst,
                                                   count=10,
                                                   timeout=20,
                                                   session=session)
        # when drop_flow is true, ping should failed(return not zero)
        # drop_flow is false, ping should success
        packets_lost = 100
        if ping_status and not drop_flow:
            raise error.TestError("Ping should success when not drop_icmp")
        elif not ping_status:
            packets_lost = utils_test.get_loss_ratio(ping_output)
            if drop_flow and packets_lost != 100:
                raise error.TestError("When drop_icmp, ping shouldn't works")
            if not drop_flow and packets_lost == 100:
                raise error.TestError("When not drop_icmp, ping should works")

        info_msg = "Correct, icmp flow %s dropped, ping '%s', "
        info_msg += "packets lost rate is: '%s'"
        logging.info(info_msg %
                     ((drop_flow and "was" or "was not"),
                      (ping_status and "failed" or "success"), packets_lost))

    def nc_connect_test(sessions,
                        addresses,
                        drop_flow=False,
                        nc_port="8899",
                        udp_model=False):
        """
        Nc connect test, check tcp and udp
        """
        nc_log = "/tmp/nc_log"
        server_cmd = "nc -l %s"
        client_cmd = "echo client | nc %s %s"
        if udp_model:
            server_cmd += " -u -w 3"
            client_cmd += " -u -w 3"
        server_cmd += " > %s &"
        client_cmd += " &"
        try:
            sessions[1].cmd_output_safe(server_cmd % (nc_port, nc_log))
            sessions[0].cmd_output_safe(client_cmd % (addresses[1], nc_port))

            nc_protocol = udp_model and "UDP" or "TCP"
            nc_connect = False
            if utils_misc.wait_for(
                    lambda: dump_catch_data(sessions[1], nc_log, "client"),
                    10,
                    0,
                    2,
                    text="Wait '%s' connect" % nc_protocol):
                nc_connect = True
            if nc_connect == drop_flow:
                err_msg = "Error, '%s' flow %s dropped, nc connect should '%s'"
                raise error.TestError(
                    err_msg % (nc_protocol, (drop_flow and "was" or "was not"),
                               (nc_connect and "failed" or "success")))

            logging.info("Correct, '%s' flow %s dropped, and nc connect %s" %
                         (nc_protocol, (drop_flow and "was" or "was not"),
                          (nc_connect and "success" or "failed")))
        finally:
            for session in sessions:
                session.cmd_output_safe("killall nc || killall ncat")
                session.cmd("%s %s" % (clean_cmd, nc_log),
                            ignore_all_errors=True)

    timeout = int(params.get("login_timeout", '360'))
    clean_cmd = params.get("clean_cmd", "rm -f")
    sessions = []
    addresses = []
    vms = []

    error.context("Init boot the vms")
    for vm_name in params.get("vms", "vm1 vm2").split():
        vms.append(env.get_vm(vm_name))
    for vm in vms:
        vm.verify_alive()
        sessions.append(vm.wait_for_login(timeout=timeout))
        addresses.append(vm.get_address())

    # set openflow rules:
    br_name = params.get("netdst", "ovs0")
    f_protocol = params.get("flow", "arp")
    f_base_options = "%s,nw_src=%s,nw_dst=%s" % (f_protocol, addresses[0],
                                                 addresses[1])
    for session in sessions:
        session.cmd("service iptables stop; iptables -F",
                    ignore_all_errors=True)
    try:
        for drop_flow in [True, False]:
            if drop_flow:
                f_command = "add-flow"
                f_options = f_base_options + ",action=drop"
                drop_icmp = eval(params.get("drop_icmp", 'True'))
                drop_tcp = eval(params.get("drop_tcp", 'True'))
                drop_udp = eval(params.get("drop_udp", 'True'))
            else:
                f_command = "mod-flows"
                f_options = f_base_options + ",action=normal"
                drop_icmp = False
                drop_tcp = False
                drop_udp = False

            error.base_context("Test prepare")
            error.context("Do %s %s on %s" % (f_command, f_options, br_name))
            utils_net.openflow_manager(br_name, f_command, f_options)

            error.context("Run tcpdump in guest %s" % vms[1].name,
                          logging.info)
            run_tcpdump_bg(sessions[1], addresses, f_protocol)

            error.context("Clean arp cache in both guest", logging.info)
            arp_entry_clean(sessions[0], addresses[1])

            error.base_context("Exec '%s' flow '%s' test" %
                               (f_protocol, drop_flow and "drop" or "normal"))
            error.context("Ping test form vm1 to vm2", logging.info)
            ping_test(sessions[0], addresses[1], drop_icmp)

            error.context("Run nc connect test via tcp", logging.info)
            nc_connect_test(sessions, addresses, drop_tcp)

            error.context("Run nc connect test via udp", logging.info)
            nc_connect_test(sessions, addresses, drop_udp, udp_model=True)

            error.context("Check tcpdump data catch", logging.info)
            tcpdump_catch_packet_test(sessions[1], drop_flow)

    finally:
        utils_net.openflow_manager(br_name, "del-flows", f_protocol)
        for session in sessions:
            session.close()
예제 #4
0
            if drop_flow:
                f_command = "add-flow"
                f_options = f_base_options + ",action=drop"
                drop_icmp = eval(params.get("drop_icmp", 'True'))
                drop_tcp = eval(params.get("drop_tcp", 'True'))
                drop_udp = eval(params.get("drop_udp", 'True'))
            else:
                f_command = "mod-flows"
                f_options = f_base_options + ",action=normal"
                drop_icmp = False
                drop_tcp = False
                drop_udp = False

            error.base_context("Test prepare")
            error.context("Do %s %s on %s" % (f_command, f_options, br_name))
            utils_net.openflow_manager(br_name, f_command, f_options)
            acl_rules = utils_net.openflow_manager(br_name,
                                                   "dump-flows").stdout
            if not acl_rules_check(acl_rules, f_options):
                raise error.TestFail("Can not find the rules from"
                                     " ovs-ofctl: %s" % acl_rules)

            error.context("Run tcpdump in guest %s" % vms[1].name,
                          logging.info)
            run_tcpdump_bg(sessions[1], addresses, f_protocol)

            if drop_flow or f_protocol is not "arp":
                error.context("Clean arp cache in both guest", logging.info)
                arp_entry_clean(addresses[1])

            error.base_context("Exec '%s' flow '%s' test" %
예제 #5
0
def run(test, params, env):
    """
    Test Step:
        1. Boot up two virtual machine
        2. Set openflow rules
        3. Run ping test, nc(tcp, udp) test, check whether openflow rules take
           effect.
    Params:
        :param test: QEMU test object
        :param params: Dictionary with the test parameters
        :param env: Dictionary with test environment.
    """
    def run_tcpdump_bg(session, addresses, dump_protocol):
        """
        Run tcpdump in background, tcpdump will exit once catch a packet
        match the rules.
        """
        tcpdump_cmd = "killall -9 tcpdump; "
        tcpdump_cmd += "tcpdump -iany -n -v %s and 'src %s and dst %s' -c 1 &"
        session.cmd_output_safe(tcpdump_cmd % (dump_protocol,
                                               addresses[0], addresses[1]))
        if not utils_misc.wait_for(lambda: tcpdump_is_alive(session),
                                   30, 0, 1, "Waiting tcpdump start..."):
            test.cancel("Error, can not run tcpdump")

    def dump_catch_data(session, dump_log, catch_reg):
        """
        Search data from dump_log
        """
        dump_info = session.cmd_output("cat %s" % dump_log)
        if re.findall(catch_reg, dump_info, re.I):
            return True
        return False

    def tcpdump_is_alive(session):
        """
        Check whether tcpdump is alive
        """
        if session.cmd_status("pidof tcpdump"):
            return False
        return True

    def tcpdump_catch_packet_test(session, drop_flow=False):
        """
        Check whether tcpdump catch match rules packets, once catch a packet
        match rules tcpdump will exit.
        when drop_flow is 'True', tcpdump couldn't catch any packets.
        """
        packet_receive = not tcpdump_is_alive(session)
        if packet_receive == drop_flow:
            err_msg = "Error, flow %s" % (drop_flow and "was" or "wasn't")
            err_msg += " dropped, tcpdump "
            err_msg += "%s " % (packet_receive and "can" or "can not")
            err_msg += "receive the packets"
            test.error(err_msg)
        logging.info("Correct, flow %s dropped, tcpdump %s receive the packet"
                     % ((drop_flow and "was" or "was not"),
                         (packet_receive and "can" or "can not")))

    def arp_entry_clean(entry=None):
        """
        Clean arp catch in guest
        """
        if not entry:
            arp_clean_cmd = "arp -n | awk '/^[1-2]/{print \"arp -d \" $1}'|sh"
        else:
            arp_clean_cmd = "arp -d %s" % entry
        for session in sessions:
            session.cmd_output_safe(arp_clean_cmd)

    def check_arp_info(session, entry, vm, match_mac=None):
        arp_info = session.cmd_output("arp -n")
        arp_entries = [_ for _ in arp_info.splitlines() if re.match(entry, _)]

        match_string = match_mac or "incomplete"

        if not arp_entries:
            test.error("Can not find arp entry in %s: %s"
                       % (vm.name, arp_info))

        if not re.findall(match_string, arp_entries[0], re.I):
            test.fail("Can not find the mac address"
                      " %s of %s in arp"
                      " entry %s" % (mac, vm.name, arp_entries[0]))

    def ping_test(session, dst, drop_flow=False):
        """
        Ping test, check icmp
        """
        ping_status, ping_output = utils_test.ping(dest=dst, count=10,
                                                   timeout=20, session=session)
        # when drop_flow is true, ping should failed(return not zero)
        # drop_flow is false, ping should success
        packets_lost = 100
        if ping_status and not drop_flow:
            test.error("Ping should success when not drop_icmp")
        elif not ping_status:
            packets_lost = utils_test.get_loss_ratio(ping_output)
            if drop_flow and packets_lost != 100:
                test.error("When drop_icmp, ping shouldn't works")
            if not drop_flow and packets_lost == 100:
                test.error("When not drop_icmp, ping should works")

        info_msg = "Correct, icmp flow %s dropped, ping '%s', "
        info_msg += "packets lost rate is: '%s'"
        logging.info(info_msg % ((drop_flow and "was" or "was not"),
                                 (ping_status and "failed" or "success"),
                                 packets_lost))

    def run_ping_bg(vm, dst):
        """
        Run ping in background
        """
        ping_cmd = "ping %s" % dst
        session = vm.wait_for_login()
        logging.info("Ping %s in background" % dst)
        session.sendline(ping_cmd)
        return session

    def check_bg_ping(session):
        ping_pattern = r"\d+ bytes from \d+.\d+.\d+.\d+:"
        ping_pattern += r" icmp_seq=\d+ ttl=\d+ time=.*? ms"
        ping_failed_pattern = r"From .*? icmp_seq=\d+ Destination"
        ping_failed_pattern += r" Host Unreachable"
        try:
            out = session.read_until_output_matches([ping_pattern,
                                                     ping_failed_pattern])
            if re.search(ping_failed_pattern, out[1]):
                return False, out[1]
            else:
                return True, out[1]
        except Exception as msg:
            return False, msg

    def file_transfer(sessions, addresses, timeout):
        prepare_cmd = "dd if=/dev/zero of=/tmp/copy_file count=1024 bs=1M"
        md5_cmd = "md5sum /tmp/copy_file"
        port = params.get("shell_port")
        prompt = params.get("shell_prompt")
        username = params.get("username")
        password = params.get("password")
        sessions[0].cmd(prepare_cmd, timeout=timeout)
        ori_md5 = sessions[0].cmd_output(md5_cmd)
        scp_cmd = (r"scp -v -o UserKnownHostsFile=/dev/null "
                   r"-o StrictHostKeyChecking=no "
                   r"-o PreferredAuthentications=password -r "
                   r"-P %s /tmp/copy_file %s@\[%s\]:/tmp/copy_file" %
                   (port, username, addresses[1]))
        sessions[0].sendline(scp_cmd)
        remote.handle_prompts(sessions[0], username, password, prompt, 600)
        new_md5 = sessions[1].cmd_output(md5_cmd)
        for session in sessions:
            session.cmd("rm -f /tmp/copy_file")
        if new_md5 != ori_md5:
            test.fail("Md5 value changed after file transfer, "
                      "original is %s and the new file"
                      " is: %s" % (ori_md5, new_md5))

    def nc_connect_test(sessions, addresses, drop_flow=False, nc_port="8899",
                        udp_model=False):
        """
        Nc connect test, check tcp and udp
        """
        nc_log = "/tmp/nc_log"
        server_cmd = "nc -l %s"
        client_cmd = "echo client | nc %s %s"
        if udp_model:
            server_cmd += " -u -w 3"
            client_cmd += " -u -w 3"
        server_cmd += " > %s &"
        client_cmd += " &"
        try:
            sessions[1].cmd_output_safe(server_cmd % (nc_port, nc_log))
            sessions[0].cmd_output_safe(client_cmd % (addresses[1], nc_port))

            nc_protocol = udp_model and "UDP" or "TCP"
            nc_connect = False
            if utils_misc.wait_for(
                    lambda: dump_catch_data(sessions[1], nc_log, "client"),
                    10, 0, 2, text="Wait '%s' connect" % nc_protocol):
                nc_connect = True
            if nc_connect == drop_flow:
                err_msg = "Error, '%s' " % nc_protocol
                err_msg += "flow %s " % (drop_flow and "was" or "was not")
                err_msg += "dropped, nc connect should"
                err_msg += " '%s'" % (nc_connect and "failed" or "success")
                test.error(err_msg)

            logging.info("Correct, '%s' flow %s dropped, and nc connect %s" %
                         (nc_protocol, (drop_flow and "was" or "was not"),
                          (nc_connect and "success" or "failed")))
        finally:
            for session in sessions:
                session.cmd_output_safe("killall nc || killall ncat")
                session.cmd("%s %s" % (clean_cmd, nc_log),
                            ignore_all_errors=True)

    def acl_rules_check(acl_rules, flow_options):
        flow_options = re.sub("action=", "actions=", flow_options)
        if "arp" in flow_options:
            flow_options = re.sub("nw_src=", "arp_spa=", flow_options)
            flow_options = re.sub("nw_dst=", "arp_tpa=", flow_options)
        acl_options = re.split(",", flow_options)
        for line in acl_rules.splitlines():
            rule = [_.lower() for _ in re.split("[ ,]", line) if _]
            item_in_rule = 0

            for acl_item in acl_options:
                if acl_item.lower() in rule:
                    item_in_rule += 1

            if item_in_rule == len(acl_options):
                return True
        return False

    def remove_plus_items(open_flow_rules):
        plus_items = ["duration", "n_packets", "n_bytes", "idle_age", "hard_age"]
        for plus_item in plus_items:
            open_flow_rules = re.sub("%s=.*?," % plus_item, "",
                                     open_flow_rules)
        return open_flow_rules

    timeout = int(params.get("login_timeout", '360'))
    prepare_timeout = int(params.get("prepare_timeout", '360'))
    clean_cmd = params.get("clean_cmd", "rm -f")
    sessions = []
    addresses = []
    vms = []
    bg_ping_session = None

    error_context.context("Init boot the vms")
    for vm_name in params.get("vms", "vm1 vm2").split():
        vms.append(env.get_vm(vm_name))
    for vm in vms:
        vm.verify_alive()
        sessions.append(vm.wait_for_login(timeout=timeout))
        addresses.append(vm.get_address())

    # set openflow rules:
    br_name = params.get("netdst", "ovs0")
    f_protocol = params.get("flow", "arp")
    f_base_options = "%s,nw_src=%s,nw_dst=%s" % (f_protocol, addresses[0],
                                                 addresses[1])
    for session in sessions:
        session.cmd("service iptables stop; iptables -F",
                    ignore_all_errors=True)

    try:
        for drop_flow in [True, False]:
            if drop_flow:
                f_command = "add-flow"
                f_options = f_base_options + ",action=drop"
                drop_icmp = eval(params.get("drop_icmp", 'True'))
                drop_tcp = eval(params.get("drop_tcp", 'True'))
                drop_udp = eval(params.get("drop_udp", 'True'))
            else:
                f_command = "mod-flows"
                f_options = f_base_options + ",action=normal"
                drop_icmp = False
                drop_tcp = False
                drop_udp = False

            error_context.base_context("Test prepare")
            error_context.context("Do %s %s on %s"
                                  % (f_command, f_options, br_name))
            utils_net.openflow_manager(br_name, f_command, f_options)
            acl_rules = utils_net.openflow_manager(br_name, "dump-flows").stdout
            if not acl_rules_check(acl_rules, f_options):
                test.fail("Can not find the rules from"
                          " ovs-ofctl: %s" % acl_rules)

            error_context.context("Run tcpdump in guest %s" % vms[1].name,
                                  logging.info)
            run_tcpdump_bg(sessions[1], addresses, f_protocol)

            if drop_flow or f_protocol is not "arp":
                error_context.context("Clean arp cache in both guest",
                                      logging.info)
                arp_entry_clean(addresses[1])

            error_context.base_context(
                "Exec '%s' flow '%s' test" %
                (f_protocol, drop_flow and "drop" or "normal"))
            if drop_flow:
                error_context.context("Ping test form vm1 to vm2",
                                      logging.info)
                ping_test(sessions[0], addresses[1], drop_icmp)
                if params.get("run_file_transfer") == "yes":
                    error_context.context("Transfer file form vm1 to vm2",
                                          logging.info)
                    file_transfer(sessions, addresses, prepare_timeout)
            else:
                error_context.context("Ping test form vm1 to vm2 in "
                                      "background", logging.info)
                bg_ping_session = run_ping_bg(vms[0], addresses[1])

            if f_protocol == 'arp' and drop_flow:
                error_context.context("Check arp inside %s" % vms[0].name,
                                      logging.info)
                check_arp_info(sessions[0], addresses[1], vms[0])
            elif f_protocol == 'arp' or params.get("check_arp") == "yes":
                time.sleep(2)
                error_context.context("Check arp inside guests.", logging.info)
                for index, address in enumerate(addresses):
                    sess_index = (index + 1) % 2
                    mac = vms[index].virtnet.get_mac_address(0)
                    check_arp_info(sessions[sess_index], address, vms[index],
                                   mac)

            error_context.context("Run nc connect test via tcp", logging.info)
            nc_connect_test(sessions, addresses, drop_tcp)

            error_context.context("Run nc connect test via udp", logging.info)
            nc_connect_test(sessions, addresses, drop_udp, udp_model=True)

            error_context.context("Check tcpdump data catch", logging.info)
            tcpdump_catch_packet_test(sessions[1], drop_flow)
    finally:
        openflow_rules_ori = utils_net.openflow_manager(br_name,
                                                        "dump-flows").stdout
        openflow_rules_ori = remove_plus_items(openflow_rules_ori)
        utils_net.openflow_manager(br_name, "del-flows", f_protocol)
        openflow_rules = utils_net.openflow_manager(br_name, "dump-flows").stdout
        openflow_rules = remove_plus_items(openflow_rules)
        removed_rule = list(set(openflow_rules_ori.splitlines()) -
                            set(openflow_rules.splitlines()))

        if f_protocol == "tcp":
            error_context.context("Run nc connect test via tcp", logging.info)
            nc_connect_test(sessions, addresses)
        elif f_protocol == "udp":
            error_context.context("Run nc connect test via udp", logging.info)
            nc_connect_test(sessions, addresses, udp_model=True)

        for session in sessions:
            session.close()
        failed_msg = []
        if (not removed_rule or
                not acl_rules_check(removed_rule[0], f_options)):
            failed_msg.append("Failed to delete %s" % f_options)
        if bg_ping_session:
            bg_ping_ok = check_bg_ping(bg_ping_session)
            bg_ping_session.close()
            if not bg_ping_ok[0]:
                failed_msg.append("There is something wrong happen in "
                                  "background ping: %s" % bg_ping_ok[1])

        if failed_msg:
            test.fail(failed_msg)
예제 #6
0
            access_sys[target] = {}
            access_sys[target]['access_cmd'] = access_param['access_cmd']
            access_sys[target]['ref_cmd'] = access_param.get('ref_cmd', "")
            access_sys[target]['clean_cmd'] = access_param.get('clean_guest',
                                                               "")
            if check_from_output:
                access_sys[target]['check_from_output'] = check_from_output
            for tgt in access_targets:
                tgt_param = access_param.object_params(tgt)
                acl_disabled = tgt_param.get("acl_disabled") == "yes"
                access_sys[target]['disabled_%s' % tgt] = acl_disabled

    error.context("Try to access target before setup the rules", logging.info)
    access_service(access_sys, access_targets, False, host_ip, ref=True)
    error.context("Disable the access in ovs", logging.info)
    br_infos = utils_net.openflow_manager(br_name, "show").stdout
    if_port = re.findall("(\d+)\(%s\)" % if_name, br_infos)
    if not if_port:
        raise error.TestNAError("Can not find %s in bridge %s" % (if_name,
                                                                  br_name))
    if_port = if_port[0]

    acl_cmd = get_acl_cmd(acl_protocol, if_port, "drop", acl_extra_options)
    utils_net.openflow_manager(br_name, "add-flow", acl_cmd)
    acl_rules = utils_net.openflow_manager(br_name, "dump-flows").stdout
    if not acl_rules_check(acl_rules, acl_cmd):
        raise error.TestFail("Can not find the rules from"
                             " ovs-ofctl: %s" % acl_rules)

    error.context("Try to acess target to exam the disable rules",
                  logging.info)
예제 #7
0
def run_openflow_test(test, params, env):
    """
    Test Step:
        1. Boot up two virtual machine
        2. Set openflow rules
        3. Run ping test, nc(tcp, udp) test, check whether openflow rules take
           effect.
    Params:
        :param test: QEMU test object
        :param params: Dictionary with the test parameters
        :param env: Dictionary with test environment.
    """
    def run_tcpdump_bg(session, addresses, dump_protocol):
        """
        Run tcpdump in background, tcpdump will exit once catch a packet
        match the rules.
        """
        tcpdump_cmd = "killall -9 tcpdump; "
        tcpdump_cmd += "tcpdump -iany -n -v %s and 'src %s and dst %s' -c 1 &"
        session.cmd_output_safe(tcpdump_cmd % (dump_protocol,
                                               addresses[0], addresses[1]))
        if not utils_misc.wait_for(lambda: tcpdump_is_alive(session),
                                   30, 0, 1, "Waiting tcpdump start..."):
            raise error.TestNAError("Error, can not run tcpdump")

    def dump_catch_data(session, dump_log, catch_reg):
        """
        Search data from dump_log
        """
        dump_info = session.cmd_output("cat %s" % dump_log)
        if re.findall(catch_reg, dump_info, re.I):
            return True
        return False

    def tcpdump_is_alive(session):
        """
        Check whether tcpdump is alive
        """
        if session.cmd_status("pidof tcpdump"):
            return False
        return True

    def tcpdump_catch_packet_test(session, drop_flow=False):
        """
        Check whether tcpdump catch match rules packets, once catch a packet
        match rules tcpdump will exit.
        when drop_flow is 'True', tcpdump couldn't catch any packets.
        """
        packet_receive = not tcpdump_is_alive(session)
        if packet_receive == drop_flow:
            err_msg = "Error, flow %s dropped, tcpdump %s receive the packets"
            raise error.TestError(err_msg % ((drop_flow and "was" or "wasn't"),
                                  (packet_receive and "can" or "can not")))
        logging.info("Correct, flow %s dropped, tcpdump %s receive the packet"
                     % ((drop_flow and "was" or "was not"),
                         (packet_receive and "can" or "can not")))

    def arp_entry_clean(session, entry=None):
        """
        Clean arp catch in guest
        """
        if not entry:
            arp_clean_cmd = "arp -n | awk '/^[1-2]/{print \"arp -d \" $1}'|sh"
        else:
            arp_clean_cmd = "arp -d %s" % entry
        for session in sessions:
            session.cmd_output_safe(arp_clean_cmd)

    def ping_test(session, dst, drop_flow=False):
        """
        Ping test, check icmp
        """
        ping_status, ping_output = utils_test.ping(dest=dst, count=10,
                                                   timeout=20, session=session)
        # when drop_flow is true, ping should failed(return not zero)
        # drop_flow is false, ping should success
        packets_lost = 100
        if ping_status and not drop_flow:
            raise error.TestError("Ping should success when not drop_icmp")
        elif not ping_status:
            packets_lost = utils_test.get_loss_ratio(ping_output)
            if drop_flow and packets_lost != 100:
                raise error.TestError("When drop_icmp, ping shouldn't works")
            if not drop_flow and packets_lost == 100:
                raise error.TestError("When not drop_icmp, ping should works")

        info_msg = "Correct, icmp flow %s dropped, ping '%s', "
        info_msg += "packets lost rate is: '%s'"
        logging.info(info_msg % ((drop_flow and "was" or "was not"),
                                 (ping_status and "failed" or "success"),
                                 packets_lost))

    def nc_connect_test(sessions, addresses, drop_flow=False, nc_port="8899",
                        udp_model=False):
        """
        Nc connect test, check tcp and udp
        """
        nc_log = "/tmp/nc_log"
        server_cmd = "nc -l %s"
        client_cmd = "echo client | nc %s %s"
        if udp_model == True:
            server_cmd += " -u -w 3"
            client_cmd += " -u -w 3"
        server_cmd += " > %s &"
        client_cmd += " &"
        try:
            sessions[1].cmd_output_safe(server_cmd % (nc_port, nc_log))
            sessions[0].cmd_output_safe(client_cmd % (addresses[1], nc_port))

            nc_protocol = udp_model and "UDP" or "TCP"
            nc_connect = False
            if utils_misc.wait_for(
                    lambda: dump_catch_data(sessions[1], nc_log, "client"),
                    10, 0, 2, text="Wait '%s' connect" % nc_protocol):
                nc_connect = True
            if nc_connect == drop_flow:
                err_msg = "Error, '%s' flow %s dropped, nc connect should '%s'"
                raise error.TestError(err_msg % (nc_protocol,
                                      (drop_flow and "was" or "was not"),
                                      (nc_connect and "failed" or "success")))

            logging.info("Correct, '%s' flow %s dropped, and nc connect %s" %
                        (nc_protocol, (drop_flow and "was" or "was not"),
                         (nc_connect and "success" or "failed")))
        finally:
            for session in sessions:
                session.cmd_output_safe("killall nc || killall ncat")
                session.cmd("%s %s" % (clean_cmd, nc_log),
                            ignore_all_errors=True)

    timeout = int(params.get("login_timeout", '360'))
    clean_cmd = params.get("clean_cmd", "rm -f")
    sessions = []
    addresses = []
    vms = []

    error.context("Init boot the vms")
    for vm_name in params.get("vms", "vm1 vm2").split():
        vms.append(env.get_vm(vm_name))
    for vm in vms:
        vm.verify_alive()
        sessions.append(vm.wait_for_login(timeout=timeout))
        addresses.append(vm.get_address())

    # set openflow rules:
    br_name = params.get("netdst", "ovs0")
    f_protocol = params.get("flow", "arp")
    f_base_options = "%s,nw_src=%s,nw_dst=%s" % (f_protocol, addresses[0],
                                                 addresses[1])
    for session in sessions:
        session.cmd("service iptables stop; iptables -F",
                    ignore_all_errors=True)
    try:
        for drop_flow in [True, False]:
            if drop_flow:
                f_command = "add-flow"
                f_options = f_base_options + ",action=drop"
                drop_icmp = eval(params.get("drop_icmp", 'True'))
                drop_tcp = eval(params.get("drop_tcp", 'True'))
                drop_udp = eval(params.get("drop_udp", 'True'))
            else:
                f_command = "mod-flows"
                f_options = f_base_options + ",action=normal"
                drop_icmp = False
                drop_tcp = False
                drop_udp = False

            error.base_context("Test prepare")
            error.context("Do %s %s on %s" % (f_command, f_options, br_name))
            utils_net.openflow_manager(br_name, f_command, f_options)

            error.context("Run tcpdump in guest %s" % vms[1].name, logging.info)
            run_tcpdump_bg(sessions[1], addresses, f_protocol)

            error.context("Clean arp cache in both guest", logging.info)
            arp_entry_clean(sessions[0], addresses[1])

            error.base_context("Exec '%s' flow '%s' test" %
                               (f_protocol, drop_flow and "drop" or "normal"))
            error.context("Ping test form vm1 to vm2", logging.info)
            ping_test(sessions[0], addresses[1], drop_icmp)

            error.context("Run nc connect test via tcp", logging.info)
            nc_connect_test(sessions, addresses, drop_tcp)

            error.context("Run nc connect test via udp", logging.info)
            nc_connect_test(sessions, addresses, drop_udp, udp_model=True)

            error.context("Check tcpdump data catch", logging.info)
            tcpdump_catch_packet_test(sessions[1], drop_flow)

    finally:
        utils_net.openflow_manager(br_name, "del-flows", f_protocol)
        for session in sessions:
            session.close()
예제 #8
0
def run(test, params, env):
    """
    Test Step:
        1. Boot up guest using the openvswitch bridge
        2. Setup related service in test enviroment(http, ftp etc.)(optional)
        3. Access the service in guest
        4. Setup access control rules in ovs to disable the access
        5. Access the service in guest
        6. Setup access control rules in ovs to enable the access
        7. Access the service in guest
        8. Delete the access control rules in ovs
        9. Access the service in guest

    Params:
        :param test: QEMU test object
        :param params: Dictionary with the test parameters
        :param env: Dictionary with test environment.
    """
    def access_service(access_sys,
                       access_targets,
                       disabled,
                       host_ip,
                       ref=False):
        err_msg = ""
        err_type = ""
        for asys in access_sys:
            for atgt in access_targets:
                logging.debug("Try to access target %s from %s" % (atgt, asys))

                access_params = access_sys[asys]
                atgt_disabled = access_params['disabled_%s' % atgt]
                if asys in vms_tags:
                    vm = env.get_vm(asys)
                    session = vm.wait_for_login(timeout=timeout)
                    run_func = session.cmd
                    remote_src = vm
                    ssh_src_ip = vm.get_address()
                else:
                    run_func = _system_output
                    remote_src = "localhost"
                    ssh_src_ip = host_ip
                if atgt in vms_tags:
                    vm = env.get_vm(atgt)
                    access_re_sub_string = vm.wait_for_get_address(0)
                else:
                    access_re_sub_string = host_ip

                access_cmd = re.sub("ACCESS_TARGET", access_re_sub_string,
                                    access_params['access_cmd'])
                ref_cmd = re.sub("ACCESS_TARGET", access_re_sub_string,
                                 access_params['ref_cmd'])

                if access_cmd in ["ssh", "telnet"]:
                    if atgt in vms_tags:
                        target_vm = env.get_vm(atgt)
                        target_ip = target_vm.get_address()
                    else:
                        target_vm = "localhost"
                        target_ip = host_ip
                    out = ""
                    out_err = ""
                    try:
                        out = remote_login(access_cmd, target_ip, remote_src,
                                           params, host_ip)
                        stat = 0
                    except remote.LoginError as err:
                        stat = 1
                        out_err = "Failed to login %s " % atgt
                        out_err += "from %s, err: %s" % (asys, err.output)
                    try:
                        out += remote_login(access_cmd, ssh_src_ip, target_vm,
                                            params, host_ip)
                    except remote.LoginError as err:
                        stat += 1
                        out_err += "Failed to login %s " % asys
                        out_err += "from %s, err: %s" % (atgt, err.output)
                    if out_err:
                        out = out_err
                else:
                    try:
                        out = run_func(access_cmd, timeout=op_timeout)
                        stat = 0
                        check_string = access_params.get("check_from_output")
                        if check_string and check_string in out:
                            stat = 1
                    except aexpect.ShellCmdError as err:
                        out = err.output
                        stat = err.status
                    except aexpect.ShellTimeoutError as err:
                        out = err.output
                        stat = 1
                        session.close()
                        session = vm.wait_for_login(timeout=timeout)
                        run_func = session.cmd
                    except process.CmdError as err:
                        out = err.result.stderr
                        stat = err.result.exit_status

                    if access_params.get("clean_cmd"):
                        try:
                            run_func(access_params['clean_cmd'])
                        except Exception:
                            pass

                if disabled and atgt_disabled and stat == 0:
                    err_msg += "Still can access %s after" % atgt
                    err_msg += " disable it from ovs. "
                    err_msg += "Command: %s. " % access_cmd
                    err_msg += "Output: %s" % out
                if disabled and atgt_disabled and stat != 0:
                    logging.debug("Can not access target as expect.")
                if not disabled and stat != 0:
                    if ref:
                        err_msg += "Can not access %s at the" % atgt
                        err_msg += " beginning. Please check your setup."
                        err_type = "ref"
                    else:
                        err_msg += "Still can not access %s" % atgt
                        err_msg += " after enable the access"
                    err_msg += "Command: %s. " % access_cmd
                    err_msg += "Output: %s" % out
                if err_msg:
                    session.close()
                    if err_type == "ref":
                        test.cancel(err_msg)
                    test.fail(err_msg)

                if not ref_cmd:
                    session.close()
                    return

                try:
                    out = run_func(ref_cmd, timeout=op_timeout)
                    stat = 0
                except aexpect.ShellCmdError as err:
                    out = err.output
                    stat = err.status
                except aexpect.ShellTimeoutError as err:
                    out = err.output
                    stat = 1
                except process.CmdError as err:
                    out = err.result.stderr
                    stat = err.result.exit_status

                if stat != 0:
                    if ref:
                        err_msg += "Refernce command failed at beginning."
                        err_type = "ref"
                    else:
                        err_msg += "Refernce command failed after setup"
                        err_msg += " the rules"
                    err_msg += "Command: %s. " % ref_cmd
                    err_msg += "Output: %s" % out
                if err_msg:
                    session.close()
                    if err_type == "ref":
                        test.cancel(err_msg)
                    test.fail(err_msg)
                if asys in vms_tags:
                    session.close()

    def get_acl_cmd(protocol, in_port, action, extra_options):
        acl_cmd = protocol.strip()
        acl_cmd += ",in_port=%s" % in_port.strip()
        if extra_options.strip():
            acl_cmd += ",%s" % ",".join(extra_options.strip().split())
        if action.strip():
            acl_cmd += ",action=%s" % action.strip()
        return acl_cmd

    def acl_rules_check(acl_rules, acl_setup_cmd):
        acl_setup_cmd = re.sub("action=", "actions=", acl_setup_cmd)
        acl_option = re.split(",", acl_setup_cmd)
        for line in acl_rules.splitlines():
            rule = [_.lower() for _ in re.split("[ ,]", line) if _]
            item_in_rule = 0

            for acl_item in acl_option:
                if acl_item.lower() in rule:
                    item_in_rule += 1

            if item_in_rule == len(acl_option):
                return True
        return False

    def remote_login(client, host, src, params_login, host_ip):
        src_name = src
        if src != "localhost":
            src_name = src.name
        logging.info("Login %s from %s" % (host, src))
        port = params_login["target_port"]
        username = params_login["username"]
        password = params_login["password"]
        prompt = params_login["shell_prompt"]
        linesep = eval("'%s'" % params_login.get("shell_linesep", r"\n"))
        quit_cmd = params.get("quit_cmd", "exit")
        if host == host_ip:
            # Try to login from guest to host.
            prompt = r"^\[.*\][\#\$]\s*$"
            linesep = "\n"
            username = params_login["host_username"]
            password = params_login["host_password"]
            quit_cmd = "exit"

        if client == "ssh":
            # We only support ssh for Linux in this test
            cmd = ("ssh -o UserKnownHostsFile=/dev/null "
                   "-o StrictHostKeyChecking=no "
                   "-o PreferredAuthentications=password -p %s %s@%s" %
                   (port, username, host))
        elif client == "telnet":
            cmd = "telnet -l %s %s %s" % (username, host, port)
        else:
            raise remote.LoginBadClientError(client)

        if src == "localhost":
            logging.debug("Login with command %s" % cmd)
            session = aexpect.ShellSession(cmd, linesep=linesep, prompt=prompt)
        else:
            if params_login.get("os_type") == "windows":
                if client == "telnet":
                    cmd = "C:\\telnet.py %s %s " % (host, username)
                    cmd += "%s \"%s\" && " % (password, prompt)
                    cmd += "C:\\wait_for_quit.py"
                cmd = "%s || ping 127.0.0.1 -n 5 -w 1000 > nul" % cmd
            else:
                cmd += " || sleep 5"
            session = src.wait_for_login()
            logging.debug("Sending login command: %s" % cmd)
            session.sendline(cmd)
        try:
            out = remote.handle_prompts(session,
                                        username,
                                        password,
                                        prompt,
                                        timeout,
                                        debug=True)
        except Exception as err:
            session.close()
            raise err
        try:
            session.cmd(quit_cmd)
            session.close()
        except Exception:
            pass
        return out

    def setup_service(setup_target):
        setup_timeout = int(params.get("setup_timeout", 360))
        if setup_target == "localhost":
            setup_func = _system_output
            os_type = "linux"
        else:
            setup_vm = env.get_vm(setup_target)
            setup_session = setup_vm.wait_for_login(timeout=timeout)
            setup_func = setup_session.cmd
            os_type = params["os_type"]

        setup_params = params.object_params(os_type)
        setup_cmd = setup_params.get("setup_cmd", "service SERVICE restart")
        prepare_cmd = setup_params.get("prepare_cmd")
        setup_cmd = re.sub("SERVICE", setup_params.get("service", ""),
                           setup_cmd)

        error_context.context(
            "Set up %s service in %s" %
            (setup_params.get("service"), setup_target), logging.info)
        setup_func(setup_cmd, timeout=setup_timeout)
        if params.get("copy_ftp_site") and setup_target != "localhost":
            ftp_site = os.path.join(data_dir.get_deps_dir(),
                                    params.get("copy_ftp_site"))
            ftp_dir = params.get("ftp_dir")
            setup_vm.copy_files_to(ftp_site, ftp_dir)

        if prepare_cmd:
            setup_func(prepare_cmd, timeout=setup_timeout)
        if setup_target != "localhost":
            setup_session.close()

    def stop_service(setup_target):
        setup_timeout = int(params.get("setup_timeout", 360))
        if setup_target == "localhost":
            setup_func = _system_output
            os_type = "linux"
        else:
            setup_vm = env.get_vm(setup_target)
            setup_session = setup_vm.wait_for_login(timeout=timeout)
            setup_func = setup_session.cmd
            os_type = params["os_type"]

        setup_params = params.object_params(os_type)
        stop_cmd = setup_params.get("stop_cmd", "service SERVICE stop")
        cleanup_cmd = setup_params.get("cleanup_cmd")
        stop_cmd = re.sub("SERVICE", setup_params.get("service", ""), stop_cmd)

        error_context.context(
            "Stop %s service in %s" %
            (setup_params.get("service"), setup_target), logging.info)
        if stop_cmd:
            setup_func(stop_cmd, timeout=setup_timeout)

        if cleanup_cmd:
            setup_func(cleanup_cmd, timeout=setup_timeout)

        if setup_target != "localhost":
            setup_session.close()

    timeout = int(params.get("login_timeout", '360'))
    op_timeout = int(params.get("op_timeout", "360"))
    acl_protocol = params['acl_protocol']
    acl_extra_options = params.get("acl_extra_options", "")

    for vm in env.get_all_vms():
        session = vm.wait_for_login(timeout=timeout)
        if params.get("disable_iptables") == "yes":
            session.cmd("iptables -F")
            #session.cmd_status_output("service iptables stop")
        if params.get("copy_scripts"):
            root_dir = data_dir.get_root_dir()
            script_dir = os.path.join(root_dir, "shared", "scripts")
            tmp_dir = params.get("tmp_dir", "C:\\")
            for script in params.get("copy_scripts").split():
                script_path = os.path.join(script_dir, script)
                vm.copy_files_to(script_path, tmp_dir)
        if params.get("copy_curl") and params.get("os_type") == "windows":
            curl_win_path = params.get("curl_win_path", "C:\\curl\\")
            session.cmd("dir {0} || mkdir {0}".format(curl_win_path))
            for script in params.get("copy_curl").split():
                curl_win_link = os.path.join(data_dir.get_deps_dir("curl"),
                                             script)
                vm.copy_files_to(curl_win_link, curl_win_path, timeout=60)
        session.close()

    vms_tags = params.objects("vms")
    br_name = params.get("netdst")
    if br_name == "private":
        br_name = params.get("priv_brname", 'atbr0')

    for setup_target in params.get("setup_targets", "").split():
        setup_service(setup_target)

    access_targets = params.get("access_targets", "localhost").split()
    deny_target = params.get("deny_target", "localhost")
    all_target = params.get("extra_target", "").split() + vms_tags
    target_port = params["target_port"]
    vm = env.get_vm(vms_tags[0])
    nic = vm.virtnet[0]
    if_name = nic.ifname
    params_nic = params.object_params("nic1")
    if params["netdst"] == "private":
        params_nic["netdst"] = params_nic.get("priv_brname", "atbr0")
    host_ip = utils_net.get_host_ip_address(params_nic)
    if deny_target in vms_tags:
        deny_vm = env.get_vm(deny_target)
        deny_vm_ip = deny_vm.wait_for_get_address(0)
    elif deny_target == "localhost":
        deny_vm_ip = host_ip
    if "NW_DST" in acl_extra_options:
        acl_extra_options = re.sub("NW_DST", deny_vm_ip, acl_extra_options)
    acl_extra_options = re.sub("TARGET_PORT", target_port, acl_extra_options)

    access_sys = {}
    for target in all_target:
        if target not in access_targets:
            if target in vms_tags:
                os_type = params["os_type"]
            else:
                os_type = "linux"
            os_params = params.object_params(os_type)
            access_param = os_params.object_params(target)
            check_from_output = access_param.get("check_from_output")

            access_sys[target] = {}
            access_sys[target]['access_cmd'] = access_param['access_cmd']
            access_sys[target]['ref_cmd'] = access_param.get('ref_cmd', "")
            access_sys[target]['clean_cmd'] = access_param.get(
                'clean_guest', "")
            if check_from_output:
                access_sys[target]['check_from_output'] = check_from_output
            for tgt in access_targets:
                tgt_param = access_param.object_params(tgt)
                acl_disabled = tgt_param.get("acl_disabled") == "yes"
                access_sys[target]['disabled_%s' % tgt] = acl_disabled

    error_context.context("Try to access target before setup the rules",
                          logging.info)
    access_service(access_sys, access_targets, False, host_ip, ref=True)
    error_context.context("Disable the access in ovs", logging.info)
    br_infos = utils_net.openflow_manager(br_name, "show").stdout.decode()
    if_port = re.findall(r"(\d+)\(%s\)" % if_name, br_infos)
    if not if_port:
        test.cancel("Can not find %s in bridge %s" % (if_name, br_name))
    if_port = if_port[0]

    acl_cmd = get_acl_cmd(acl_protocol, if_port, "drop", acl_extra_options)
    utils_net.openflow_manager(br_name, "add-flow", acl_cmd)
    acl_rules = utils_net.openflow_manager(br_name,
                                           "dump-flows").stdout.decode()
    if not acl_rules_check(acl_rules, acl_cmd):
        test.fail("Can not find the rules from ovs-ofctl: %s" % acl_rules)

    error_context.context("Try to acess target to exam the disable rules",
                          logging.info)
    access_service(access_sys, access_targets, True, host_ip)
    error_context.context("Enable the access in ovs", logging.info)
    acl_cmd = get_acl_cmd(acl_protocol, if_port, "normal", acl_extra_options)
    utils_net.openflow_manager(br_name, "mod-flows", acl_cmd)
    acl_rules = utils_net.openflow_manager(br_name,
                                           "dump-flows").stdout.decode()
    if not acl_rules_check(acl_rules, acl_cmd):
        test.fail("Can not find the rules from ovs-ofctl: %s" % acl_rules)
    error_context.context("Try to acess target to exam the enable rules",
                          logging.info)
    access_service(access_sys, access_targets, False, host_ip)
    error_context.context("Delete the access rules in ovs", logging.info)
    acl_cmd = get_acl_cmd(acl_protocol, if_port, "", acl_extra_options)
    utils_net.openflow_manager(br_name, "del-flows", acl_cmd)
    acl_rules = utils_net.openflow_manager(br_name,
                                           "dump-flows").stdout.decode()
    if acl_rules_check(acl_rules, acl_cmd):
        test.fail("Still can find the rules from ovs-ofctl: %s" % acl_rules)
    error_context.context("Try to acess target to exam after delete the rules",
                          logging.info)
    access_service(access_sys, access_targets, False, host_ip)

    for setup_target in params.get("setup_targets", "").split():
        stop_service(setup_target)
예제 #9
0
def run(test, params, env):
    """
    Test Step:
        1. Boot up guest using the openvswitch bridge
        2. Setup related service in test enviroment(http, ftp etc.)(optional)
        3. Access the service in guest
        4. Setup access control rules in ovs to disable the access
        5. Access the service in guest
        6. Setup access control rules in ovs to enable the access
        7. Access the service in guest
        8. Delete the access control rules in ovs
        9. Access the service in guest

    Params:
        :param test: QEMU test object
        :param params: Dictionary with the test parameters
        :param env: Dictionary with test environment.
    """
    def access_service(access_sys, access_targets, disabled, host_ip,
                       ref=False):
        err_msg = ""
        err_type = ""
        for asys in access_sys:
            for atgt in access_targets:
                logging.debug("Try to access target %s from %s" % (atgt, asys))

                access_params = access_sys[asys]
                atgt_disabled = access_params['disabled_%s' % atgt]
                if asys in vms_tags:
                    vm = env.get_vm(asys)
                    session = vm.wait_for_login(timeout=timeout)
                    run_func = session.cmd
                    remote_src = vm
                    ssh_src_ip = vm.get_address()
                else:
                    run_func = _system_output
                    remote_src = "localhost"
                    ssh_src_ip = host_ip
                if atgt in vms_tags:
                    vm = env.get_vm(atgt)
                    access_re_sub_string = vm.wait_for_get_address(0)
                else:
                    access_re_sub_string = host_ip

                access_cmd = re.sub("ACCESS_TARGET", access_re_sub_string,
                                    access_params['access_cmd'])
                ref_cmd = re.sub("ACCESS_TARGET", access_re_sub_string,
                                 access_params['ref_cmd'])

                if access_cmd in ["ssh", "telnet"]:
                    if atgt in vms_tags:
                        target_vm = env.get_vm(atgt)
                        target_ip = target_vm.get_address()
                    else:
                        target_vm = "localhost"
                        target_ip = host_ip
                    out = ""
                    out_err = ""
                    try:
                        out = remote_login(access_cmd, target_ip,
                                           remote_src, params, host_ip)
                        stat = 0
                    except remote.LoginError as err:
                        stat = 1
                        out_err = "Failed to login %s " % atgt
                        out_err += "from %s, err: %s" % (asys, err.output)
                    try:
                        out += remote_login(access_cmd, ssh_src_ip,
                                            target_vm, params, host_ip)
                    except remote.LoginError as err:
                        stat += 1
                        out_err += "Failed to login %s " % asys
                        out_err += "from %s, err: %s" % (atgt, err.output)
                    if out_err:
                        out = out_err
                else:
                    try:
                        out = run_func(access_cmd, timeout=op_timeout)
                        stat = 0
                        check_string = access_params.get("check_from_output")
                        if check_string and check_string in out:
                            stat = 1
                    except aexpect.ShellCmdError as err:
                        out = err.output
                        stat = err.status
                    except aexpect.ShellTimeoutError as err:
                        out = err.output
                        stat = 1
                        session.close()
                        session = vm.wait_for_login(timeout=timeout)
                        run_func = session.cmd
                    except process.CmdError as err:
                        out = err.result.stderr
                        stat = err.result.exit_status

                    if access_params.get("clean_cmd"):
                        try:
                            run_func(access_params['clean_cmd'])
                        except Exception:
                            pass

                if disabled and atgt_disabled and stat == 0:
                    err_msg += "Still can access %s after" % atgt
                    err_msg += " disable it from ovs. "
                    err_msg += "Command: %s. " % access_cmd
                    err_msg += "Output: %s" % out
                if disabled and atgt_disabled and stat != 0:
                    logging.debug("Can not access target as expect.")
                if not disabled and stat != 0:
                    if ref:
                        err_msg += "Can not access %s at the" % atgt
                        err_msg += " beginning. Please check your setup."
                        err_type = "ref"
                    else:
                        err_msg += "Still can not access %s" % atgt
                        err_msg += " after enable the access"
                    err_msg += "Command: %s. " % access_cmd
                    err_msg += "Output: %s" % out
                if err_msg:
                    session.close()
                    if err_type == "ref":
                        test.cancel(err_msg)
                    test.fail(err_msg)

                if not ref_cmd:
                    session.close()
                    return

                try:
                    out = run_func(ref_cmd, timeout=op_timeout)
                    stat = 0
                except aexpect.ShellCmdError as err:
                    out = err.output
                    stat = err.status
                except aexpect.ShellTimeoutError as err:
                    out = err.output
                    stat = 1
                except process.CmdError as err:
                    out = err.result.stderr
                    stat = err.result.exit_status

                if stat != 0:
                    if ref:
                        err_msg += "Refernce command failed at beginning."
                        err_type = "ref"
                    else:
                        err_msg += "Refernce command failed after setup"
                        err_msg += " the rules"
                    err_msg += "Command: %s. " % ref_cmd
                    err_msg += "Output: %s" % out
                if err_msg:
                    session.close()
                    if err_type == "ref":
                        test.cancel(err_msg)
                    test.fail(err_msg)
                session.close()

    def get_acl_cmd(protocol, in_port, action, extra_options):
        acl_cmd = protocol.strip()
        acl_cmd += ",in_port=%s" % in_port.strip()
        if extra_options.strip():
            acl_cmd += ",%s" % ",".join(extra_options.strip().split())
        if action.strip():
            acl_cmd += ",action=%s" % action.strip()
        return acl_cmd

    def acl_rules_check(acl_rules, acl_setup_cmd):
        acl_setup_cmd = re.sub("action=", "actions=", acl_setup_cmd)
        acl_option = re.split(",", acl_setup_cmd)
        for line in acl_rules.splitlines():
            rule = [_.lower() for _ in re.split("[ ,]", line) if _]
            item_in_rule = 0

            for acl_item in acl_option:
                if acl_item.lower() in rule:
                    item_in_rule += 1

            if item_in_rule == len(acl_option):
                return True
        return False

    def remote_login(client, host, src, params_login, host_ip):
        src_name = src
        if src != "localhost":
            src_name = src.name
        logging.info("Login %s from %s" % (host, src))
        port = params_login["target_port"]
        username = params_login["username"]
        password = params_login["password"]
        prompt = params_login["shell_prompt"]
        linesep = eval("'%s'" % params_login.get("shell_linesep", r"\n"))
        quit_cmd = params.get("quit_cmd", "exit")
        if host == host_ip:
            # Try to login from guest to host.
            prompt = r"^\[.*\][\#\$]\s*$"
            linesep = "\n"
            username = params_login["host_username"]
            password = params_login["host_password"]
            quit_cmd = "exit"

        if client == "ssh":
            # We only support ssh for Linux in this test
            cmd = ("ssh -o UserKnownHostsFile=/dev/null "
                   "-o StrictHostKeyChecking=no "
                   "-o PreferredAuthentications=password -p %s %s@%s" %
                   (port, username, host))
        elif client == "telnet":
            cmd = "telnet -l %s %s %s" % (username, host, port)
        else:
            raise remote.LoginBadClientError(client)

        if src == "localhost":
            logging.debug("Login with command %s" % cmd)
            session = aexpect.ShellSession(cmd, linesep=linesep, prompt=prompt)
        else:
            if params_login.get("os_type") == "windows":
                if client == "telnet":
                    cmd = "C:\\telnet.py %s %s " % (host, username)
                    cmd += "%s \"%s\" && " % (password, prompt)
                    cmd += "C:\\wait_for_quit.py"
                cmd = "%s || ping 127.0.0.1 -n 5 -w 1000 > nul" % cmd
            else:
                cmd += " || sleep 5"
            session = src.wait_for_login()
            logging.debug("Sending login command: %s" % cmd)
            session.sendline(cmd)
        try:
            out = remote.handle_prompts(session, username, password,
                                        prompt, timeout, debug=True)
        except Exception as err:
            session.close()
            raise err
        try:
            session.cmd(quit_cmd)
            session.close()
        except Exception:
            pass
        return out

    def setup_service(setup_target):
        setup_timeout = int(params.get("setup_timeout", 360))
        if setup_target == "localhost":
            setup_func = _system_output
            os_type = "linux"
        else:
            setup_vm = env.get_vm(setup_target)
            setup_session = setup_vm.wait_for_login(timeout=timeout)
            setup_func = setup_session.cmd
            os_type = params["os_type"]

        setup_params = params.object_params(os_type)
        setup_cmd = setup_params.get("setup_cmd", "service SERVICE restart")
        prepare_cmd = setup_params.get("prepare_cmd")
        setup_cmd = re.sub("SERVICE", setup_params.get("service", ""),
                           setup_cmd)

        error_context.context("Set up %s service in %s"
                              % (setup_params.get("service"), setup_target),
                              logging.info)
        if prepare_cmd:
            setup_func(prepare_cmd, timeout=setup_timeout)
        setup_func(setup_cmd, timeout=setup_timeout)
        if setup_target != "localhost":
            setup_session.close()

    def stop_service(setup_target):
        setup_timeout = int(params.get("setup_timeout", 360))
        if setup_target == "localhost":
            setup_func = _system_output
            os_type = "linux"
        else:
            setup_vm = env.get_vm(setup_target)
            setup_session = setup_vm.wait_for_login(timeout=timeout)
            setup_func = setup_session.cmd
            os_type = params["os_type"]

        setup_params = params.object_params(os_type)
        stop_cmd = setup_params.get("stop_cmd", "service SERVICE stop")
        cleanup_cmd = setup_params.get("cleanup_cmd")
        stop_cmd = re.sub("SERVICE", setup_params.get("service", ""),
                          stop_cmd)

        error_context.context("Stop %s service in %s"
                              % (setup_params.get("service"), setup_target),
                              logging.info)
        if stop_cmd:
            setup_func(stop_cmd, timeout=setup_timeout)

        if cleanup_cmd:
            setup_func(cleanup_cmd, timeout=setup_timeout)

        if setup_target != "localhost":
            setup_session.close()

    timeout = int(params.get("login_timeout", '360'))
    op_timeout = int(params.get("op_timeout", "360"))
    acl_protocol = params['acl_protocol']
    acl_extra_options = params.get("acl_extra_options", "")

    for vm in env.get_all_vms():
        session = vm.wait_for_login(timeout=timeout)
        if params.get("disable_iptables") == "yes":
            session.cmd("iptables -F")
            #session.cmd_status_output("service iptables stop")
        if params.get("copy_scripts"):
            root_dir = data_dir.get_root_dir()
            script_dir = os.path.join(root_dir, "shared", "scripts")
            tmp_dir = params.get("tmp_dir", "C:\\")
            for script in params.get("copy_scripts").split():
                script_path = os.path.join(script_dir, script)
                vm.copy_files_to(script_path, tmp_dir)
        if params.get("os_type") == "windows":
            curl_win_path = params.get("curl_win_path", "C:\\curl\\")
            session.cmd("dir {0} || mkdir {0}".format(curl_win_path))
            for script in params.get("copy_curl").split():
                curl_win_link = os.path.join(data_dir.get_deps_dir("curl"), script)
                vm.copy_files_to(curl_win_link, curl_win_path, timeout=60)
        session.close()

    vms_tags = params.objects("vms")
    br_name = params.get("netdst")
    if br_name == "private":
        br_name = params.get("priv_brname", 'autotest-prbr0')

    for setup_target in params.get("setup_targets", "").split():
        setup_service(setup_target)

    access_targets = params.get("access_targets", "localhost").split()
    deny_target = params.get("deny_target", "localhost")
    all_target = params.get("extra_target", "").split() + vms_tags
    target_port = params["target_port"]
    vm = env.get_vm(vms_tags[0])
    nic = vm.virtnet[0]
    if_name = nic.ifname
    params_nic = params.object_params("nic1")
    if params["netdst"] == "private":
        params_nic["netdst"] = params_nic.get("priv_brname", "atbr0")
    host_ip = utils_net.get_host_ip_address(params_nic)
    if deny_target in vms_tags:
        deny_vm = env.get_vm(deny_target)
        deny_vm_ip = deny_vm.wait_for_get_address(0)
    elif deny_target == "localhost":
        deny_vm_ip = host_ip
    if "NW_DST" in acl_extra_options:
        acl_extra_options = re.sub("NW_DST", deny_vm_ip, acl_extra_options)
    acl_extra_options = re.sub("TARGET_PORT", target_port, acl_extra_options)

    access_sys = {}
    for target in all_target:
        if target not in access_targets:
            if target in vms_tags:
                os_type = params["os_type"]
            else:
                os_type = "linux"
            os_params = params.object_params(os_type)
            access_param = os_params.object_params(target)
            check_from_output = access_param.get("check_from_output")

            access_sys[target] = {}
            access_sys[target]['access_cmd'] = access_param['access_cmd']
            access_sys[target]['ref_cmd'] = access_param.get('ref_cmd', "")
            access_sys[target]['clean_cmd'] = access_param.get('clean_guest',
                                                               "")
            if check_from_output:
                access_sys[target]['check_from_output'] = check_from_output
            for tgt in access_targets:
                tgt_param = access_param.object_params(tgt)
                acl_disabled = tgt_param.get("acl_disabled") == "yes"
                access_sys[target]['disabled_%s' % tgt] = acl_disabled

    error_context.context("Try to access target before setup the rules",
                          logging.info)
    access_service(access_sys, access_targets, False, host_ip, ref=True)
    error_context.context("Disable the access in ovs", logging.info)
    br_infos = utils_net.openflow_manager(br_name, "show").stdout
    if_port = re.findall(r"(\d+)\(%s\)" % if_name, br_infos)
    if not if_port:
        test.cancel("Can not find %s in bridge %s" % (if_name, br_name))
    if_port = if_port[0]

    acl_cmd = get_acl_cmd(acl_protocol, if_port, "drop", acl_extra_options)
    utils_net.openflow_manager(br_name, "add-flow", acl_cmd)
    acl_rules = utils_net.openflow_manager(br_name, "dump-flows").stdout
    if not acl_rules_check(acl_rules, acl_cmd):
        test.fail("Can not find the rules from ovs-ofctl: %s" % acl_rules)

    error_context.context("Try to acess target to exam the disable rules",
                          logging.info)
    access_service(access_sys, access_targets, True, host_ip)
    error_context.context("Enable the access in ovs", logging.info)
    acl_cmd = get_acl_cmd(acl_protocol, if_port, "normal", acl_extra_options)
    utils_net.openflow_manager(br_name, "mod-flows", acl_cmd)
    acl_rules = utils_net.openflow_manager(br_name, "dump-flows").stdout
    if not acl_rules_check(acl_rules, acl_cmd):
        test.fail("Can not find the rules from ovs-ofctl: %s" % acl_rules)
    error_context.context("Try to acess target to exam the enable rules",
                          logging.info)
    access_service(access_sys, access_targets, False, host_ip)
    error_context.context("Delete the access rules in ovs", logging.info)
    acl_cmd = get_acl_cmd(acl_protocol, if_port, "", acl_extra_options)
    utils_net.openflow_manager(br_name, "del-flows", acl_cmd)
    acl_rules = utils_net.openflow_manager(br_name, "dump-flows").stdout
    if acl_rules_check(acl_rules, acl_cmd):
        test.fail("Still can find the rules from ovs-ofctl: %s" % acl_rules)
    error_context.context("Try to acess target to exam after delete the rules",
                          logging.info)
    access_service(access_sys, access_targets, False, host_ip)

    for setup_target in params.get("setup_targets", "").split():
        stop_service(setup_target)
예제 #10
0
            access_sys[target] = {}
            access_sys[target]['access_cmd'] = access_param['access_cmd']
            access_sys[target]['ref_cmd'] = access_param.get('ref_cmd', "")
            access_sys[target]['clean_cmd'] = access_param.get('clean_guest',
                                                               "")
            if check_from_output:
                access_sys[target]['check_from_output'] = check_from_output
            for tgt in access_targets:
                tgt_param = access_param.object_params(tgt)
                acl_disabled = tgt_param.get("acl_disabled") == "yes"
                access_sys[target]['disabled_%s' % tgt] = acl_disabled

    error.context("Try to access target before setup the rules", logging.info)
    access_service(access_sys, access_targets, False, host_ip, ref=True)
    error.context("Disable the access in ovs", logging.info)
    br_infos = utils_net.openflow_manager(br_name, "show").stdout
    if_port = re.findall("(\d+)\(%s\)" % if_name, br_infos)
    if not if_port:
        raise error.TestNAError("Can not find %s in bridge %s" % (if_name,
                                                                  br_name))
    if_port = if_port[0]

    acl_cmd = get_acl_cmd(acl_protocol, if_port, "drop", acl_extra_options)
    utils_net.openflow_manager(br_name, "add-flow", acl_cmd)
    acl_rules = utils_net.openflow_manager(br_name, "dump-flows").stdout
    if not acl_rules_check(acl_rules, acl_cmd):
        raise error.TestFail("Can not find the rules from"
                             " ovs-ofctl: %s" % acl_rules)

    error.context("Try to acess target to exam the disable rules",
                  logging.info)