diff --git a/docs/testplan/syslog/Syslog_Protocol_Filter_TrapSeverityLevel_test_plan.md b/docs/testplan/syslog/Syslog_Protocol_Filter_TrapSeverityLevel_test_plan.md new file mode 100644 index 00000000000..db6f9d3fb8b --- /dev/null +++ b/docs/testplan/syslog/Syslog_Protocol_Filter_TrapSeverityLevel_test_plan.md @@ -0,0 +1,104 @@ +# Syslog Protocol Filter Trap severity level Test Plan + +## Related documents + +| **Document Name** | **Link** | +|-------------------|----------| +| Syslog new functionality HLD | [https://github.com/sonic-net/SONiC/pull/1218]| + + +## Overview + +Extended following functionality in syslog: + +Configure remote syslog servers: protocol, filter, trap severity level +Update global syslog configuration: trap severity level, message format + +### Scope + +The test is to verify syslog new functionality + +### Scale / Performance + +No scale/performance test involved in this test plan + +### Related **DUT** CLI commands + +``` +User interface: + +config +|--- syslog + |--- add OPTIONS + |--- del + +Options: + +config syslog add server_ip + +-s|--source - source ip address +-p|--port - server udp port +-r|--vrf - vrf device + + +show +|--- syslog +``` + +### Supported topology +The tests will be supported on any topo. + +### Test cases #1 - Configure syslog server with source:unset/unset +1. Configure syslog server with source:unset/unset like below: +``` +config syslog add 2.2.2.2 +``` +2. Check syslog config by show syslog, the result should like below: + ``` + # show syslog + SERVER SOURCE PORT VRF + ---------- ---------- ------ -------- + 2.2.2.2 N/A 514 default + ``` +3. Check the corresponding interface will send syslog message with port 514 on dut +``` +# show syslog +SERVER SOURCE PORT VRF +---------- ---------- ------ -------- +2.2.2.2 N/A 514 default +``` +4. Change syslog protocol to tcp +``` +sonic-db-cli CONFIG_DB HSET 'SYSLOG_SERVER|2.2.2.2' 'protocol' 'tcp' +``` +5. Send message with tcp protocol and verify packet sent +6. Send message with udp and verify it did not send +7. Configure include filter with filter regex +``` +sonic-db-cli CONFIG_DB hset 'SYSLOG_SERVER|2.2.2.2' 'filter_type' 'include' 'filter_regex' 'sonic' +``` +8. Send message with include filter and verify packet sent +9. Send message without include filter and verify packet did not send +10. Configure exclude filter +``` +sonic-db-cli CONFIG_DB hset 'SYSLOG_SERVER|2.2.2.2' 'filter_type' 'exclude' 'filter_regex' 'aa' +``` +11. Send message with exclude regex and verify packet not sent +12. Send message without exclude regex and verify packet sent +13. Remove exclude filter +``` +sonic-db-cli CONFIG_DB hdel 'SYSLOG_SERVER|2.2.2.2' 'filter_type' 'exclude' 'filter_regex' 'aa' +``` +14. Send messages with different severities and make sure they will be filtered according to default severity +15. Change global severity and make sure it works according to messages you sent +16. Remove syslog config +``` +config syslog del 2.2.2.2 +``` + +14. Send messages with different severities and make sure they will be filtered according to default severity +15. Change global severity and make sure it works according to messages you sent +16. Remove syslog config +``` +config syslog del 2.2.2.2 +``` diff --git a/tests/syslog/syslog_utils.py b/tests/syslog/syslog_utils.py index 44ffa4be605..d173c591ecf 100644 --- a/tests/syslog/syslog_utils.py +++ b/tests/syslog/syslog_utils.py @@ -2,6 +2,8 @@ Helpful utilities for writing tests for the syslog feature. """ import logging +import random +import string import time import os @@ -110,7 +112,7 @@ def replace_ip_neigh(dut, neighbour, neigh_mac_addr, dev): dev=dev)) -def capture_syslog_packets(dut, tcpdump_cmd): +def capture_syslog_packets(dut, tcpdump_cmd, logger_flags='', logger_msg=''): """ Capture syslog packets @@ -130,8 +132,10 @@ def capture_syslog_packets(dut, tcpdump_cmd): logging.debug("Generating log message from DUT") # Generate syslog msgs from the DUT logger_info_msg_count = 20 + default_priority = '--priority INFO' + random_msg = ''.join(random.choice(string.ascii_letters) for _ in range(logger_info_msg_count)) for i in range(logger_info_msg_count): - dut.shell("logger --priority INFO ....{}".format("i")) + dut.shell("logger {flags} ....{msg}".format(flags=default_priority+''+logger_flags, msg=random_msg+logger_msg)) time.sleep(0.2) # wait for stoping tcpdump diff --git a/tests/syslog/test_syslog_source_ip.py b/tests/syslog/test_syslog_source_ip.py index 71d6193fba7..869a127f638 100644 --- a/tests/syslog/test_syslog_source_ip.py +++ b/tests/syslog/test_syslog_source_ip.py @@ -351,11 +351,13 @@ def check_syslog_config_nonexist(self, port, vrf_list, is_set_source, is_set_vrf "Syslog config: server_ip {}, source_ip {}, vrf {}, port {} still exist".format( v["syslog_server_ip"], source_ip, vrf, port)) - def check_syslog_msg_is_sent(self, routed_interfaces, mgmt_interface, port, vrf_list, is_set_source): + def check_syslog_msg_is_sent(self, routed_interfaces, mgmt_interface, port, vrf_list, is_set_source, + logger_flags='', logger_msg=''): thread_pool = [] for vrf in vrf_list: def check_syslog_one_vrf(routed_interfaces, port, vrf): - tcpdump_file = self.gen_tcpdump_cmd_and_capture_syslog_packets(routed_interfaces, port, vrf) + tcpdump_file = self.gen_tcpdump_cmd_and_capture_syslog_packets(routed_interfaces, port, vrf, + logger_flags, logger_msg) for k, v in list(SYSLOG_TEST_DATA[vrf].items()): if self.is_link_local_ip(v["source_ip"]): continue @@ -383,11 +385,13 @@ def is_link_local_ip(self, ip): return True return False - def check_syslog_msg_is_stopped(self, routed_interfaces, mgmt_interface, port, vrf_list, is_set_source): + def check_syslog_msg_is_stopped(self, routed_interfaces, mgmt_interface, port, vrf_list, is_set_source, + logger_flags='', logger_msg=''): thread_pool = [] for vrf in vrf_list: def check_no_syslog_one_vrf(routed_interfaces, port, vrf): - tcpdump_file = self.gen_tcpdump_cmd_and_capture_syslog_packets(routed_interfaces, port, vrf) + tcpdump_file = self.gen_tcpdump_cmd_and_capture_syslog_packets(routed_interfaces, port, vrf, + logger_flags, logger_msg) for k, v in list(SYSLOG_TEST_DATA[vrf].items()): source_ip = v["source_ip"].split("/")[0] if is_set_source else None pytest_assert( @@ -407,7 +411,7 @@ def check_no_syslog_one_vrf(routed_interfaces, port, vrf): for thread in thread_pool: thread.join(60) - def gen_tcpdump_cmd_and_capture_syslog_packets(self, routed_interfaces, port, vrf): + def gen_tcpdump_cmd_and_capture_syslog_packets(self, routed_interfaces, port, vrf, logger_flags='', logger_msg=''): if vrf == VRF_LIST[0]: tcpdump_interface = routed_interfaces[0] else: @@ -416,7 +420,7 @@ def gen_tcpdump_cmd_and_capture_syslog_packets(self, routed_interfaces, port, vr .format(tcpdump_capture_time=TCPDUMP_CAPTURE_TIME, interface=tcpdump_interface, port=port if port else SYSLOG_DEFAULT_PORT, dut_pcap_file=DUT_PCAP_FILEPATH.format(vrf=vrf)) - tcpdump_file = capture_syslog_packets(self.duthost, tcpdump_cmd) + tcpdump_file = capture_syslog_packets(self.duthost, tcpdump_cmd, logger_flags, logger_msg) return tcpdump_file @pytest.mark.parametrize("syslog_config_combination_case", SYSLOG_CONFIG_COMBINATION_CASE) @@ -595,3 +599,112 @@ def test_remove_vrf_exist_syslog_config(self, duthosts, enum_rand_one_per_hwsku_ logger.info("Check there is an error prompt:{}".format(err_msg)) pytest_assert(re.search(expected_msg, err_msg), "Error msg is not correct: Expectd msg:{}, actual msg:{}".format(expected_msg, err_msg)) + + def test_syslog_protocol_filter_severity(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, + enum_frontend_asic_index, routed_interfaces, mgmt_interface): + """ + Validates syslog protocol, filter and severity work + + 1. Add syslog config + 2. Check adding syslog config succeeds + 3. Add protocol tcp and verify changes + 4. Send message with tcp protocol and verify packet send + 5. Send message with udp protocol and verify packet not send + 6. Configure include filter + 7. Send message with include filter and verify packet send + 8. Send message without include filter and verify packet not send + 9. Remove include filter + 10. Configure exclude filter + 11. Send message with exclude regex and verify packet not send + 12. Send message without exclude filter and verify packet send + 13. Remove exclude filter + 14. Send message with not default syslog severity and verify it not sent + """ + syslog_config = {"is_set_vrf": False, "is_set_source": True, "port": 650, "vrf_list": 'default'} + default_vrf_rsyslog_ip = '100.100.100.1' + self.duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] + self.asichost = self.duthost.asic_instance(enum_frontend_asic_index) + port = syslog_config["port"] + vrf_list = syslog_config["vrf_list"].split() + is_set_source = syslog_config["is_set_source"] + is_set_vrf = syslog_config["is_set_vrf"] + + with allure.step("Add syslog config"): + self.add_syslog_config(port, vrf_list=vrf_list, is_set_source=is_set_source, is_set_vrf=is_set_vrf) + + with allure.step("Check syslog config is configured successfully"): + self.check_syslog_config_exist( + port, vrf_list=vrf_list, is_set_source=is_set_source, is_set_vrf=is_set_vrf) + + with allure.step("Configure protocol and verify"): + self.duthost.shell('sonic-db-cli CONFIG_DB hset "SYSLOG_SERVER|{0}" "protocol" "tcp"' + .format(default_vrf_rsyslog_ip)) + + with allure.step("Check interface of {} send syslog msg ".format(routed_interfaces[0])): + logger_flags = '--protocol tcp' + self.check_syslog_msg_is_sent(routed_interfaces, mgmt_interface, port, vrf_list=vrf_list, + is_set_source=is_set_source, logger_flags=logger_flags) + + with allure.step("Check interface of {} will not send syslog msg ".format(routed_interfaces[0])): + logger_flags = '--protocol udp' + self.check_syslog_msg_is_stopped(routed_interfaces, mgmt_interface, port, vrf_list=vrf_list, + is_set_source=is_set_source, logger_flags=logger_flags) + + with allure.step("Configure include filter and verify"): + filter_regex = 'sonic' + self.duthost.shell('sonic-db-cli CONFIG_DB hset "SYSLOG_SERVER|{0}" ' + '"filter_type" "include" "filter_regex" {1}'.format( + default_vrf_rsyslog_ip, filter_regex)) + + with allure.step("Check interface of {} send syslog msg with include regex".format(routed_interfaces[0])): + self.check_syslog_msg_is_sent(routed_interfaces, mgmt_interface, port, vrf_list=vrf_list, + is_set_source=is_set_source, logger_flags=logger_flags, + logger_msg=filter_regex) + + with allure.step("Check interface of {} will not send without include msg ".format(routed_interfaces[0])): + self.check_syslog_msg_is_stopped(routed_interfaces, mgmt_interface, port, vrf_list=vrf_list, + is_set_source=is_set_source, logger_flags=logger_flags) + + with allure.step("Remove include filter and verify"): + self.duthost.shell('sonic-db-cli CONFIG_DB hdel ' + '"SYSLOG_SERVER|{0}" "filter_type"'.format(default_vrf_rsyslog_ip)) + + with allure.step("Configure exclude filter and verify"): + filter_regex = 'aa' + self.duthost.shell('sonic-db-cli CONFIG_DB hset' + ' "SYSLOG_SERVER|{0}" "filter_type" "exclude" "filter_regex" {1}'.format( + default_vrf_rsyslog_ip, filter_regex)) + + with allure.step("Check interface of {} will not send syslog msg with exclude".format(routed_interfaces[0])): + self.check_syslog_msg_is_stopped(routed_interfaces, mgmt_interface, port, vrf_list=vrf_list, + is_set_source=is_set_source, logger_flags=logger_flags, + logger_msg=filter_regex) + + with allure.step("Check interface of {} send syslog msg without exclude filter".format(routed_interfaces[0])): + self.check_syslog_msg_is_sent(routed_interfaces, mgmt_interface, port, vrf_list=vrf_list, + is_set_source=is_set_source, logger_flags=logger_flags, + logger_msg=filter_regex) + + with allure.step("Remove exclude filter and verify"): + self.duthost.shell('sonic-db-cli CONFIG_DB hdel ' + '"SYSLOG_SERVER|{0}" "filter_type"'.format(default_vrf_rsyslog_ip)) + + with allure.step("Change severity level to notice"): + self.duthost.shell('sonic-db-cli CONFIG_DB hset' + ' "SYSLOG_SERVER|{0}" "severity" "notice"'.format(default_vrf_rsyslog_ip)) + + with allure.step("Check interface of {} will not send syslog msg due to severity level".format( + routed_interfaces[0])): + self.check_syslog_msg_is_stopped(routed_interfaces, mgmt_interface, port, vrf_list=vrf_list, + is_set_source=is_set_source, logger_flags=logger_flags) + + with allure.step("Remove syslog config"): + self.remove_syslog_config(vrf_list=vrf_list) + + with allure.step("Check syslog config is removed"): + self.check_syslog_config_nonexist(port, vrf_list=vrf_list, is_set_source=is_set_source, + is_set_vrf=is_set_vrf) + + with allure.step("Check interface of {} will not send syslog msg ".format(routed_interfaces[0])): + self.check_syslog_msg_is_stopped(routed_interfaces, mgmt_interface, port, vrf_list=vrf_list, + is_set_source=is_set_source)