diff --git a/scripts/caclmgrd b/scripts/caclmgrd index 914547ad53b2..4af588e28de6 100755 --- a/scripts/caclmgrd +++ b/scripts/caclmgrd @@ -52,6 +52,7 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): Attributes: config_db: Handle to Config Redis database via SwSS SDK """ + FEATURE_TABLE = "FEATURE" ACL_TABLE = "ACL_TABLE" ACL_RULE = "ACL_RULE" DEVICE_METADATA_TABLE = "DEVICE_METADATA" @@ -117,6 +118,10 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): self.namespace_docker_mgmt_ip = {} self.namespace_docker_mgmt_ipv6 = {} + # Get all features that are present {feature_name : True/False} + self.feature_present = {} + self.update_feature_present() + metadata = self.config_db_map[DEFAULT_NAMESPACE].get_table(self.DEVICE_METADATA_TABLE) if 'subtype' in metadata['localhost'] and metadata['localhost']['subtype'] == 'DualToR': self.DualToR = True @@ -201,6 +206,12 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): tcp_flags_str = tcp_flags_str[:-1] return tcp_flags_str + def update_feature_present(self): + feature_tb_info = self.config_db_map[DEFAULT_NAMESPACE].get_table(self.FEATURE_TABLE) + if feature_tb_info: + for k, v in feature_tb_info.items(): + self.feature_present[k] = True + def generate_block_ip2me_traffic_iptables_commands(self, namespace): INTERFACE_TABLE_NAME_LIST = [ "LOOPBACK_INTERFACE", diff --git a/tests/caclmgrd/caclmgrd_feature_test.py b/tests/caclmgrd/caclmgrd_feature_test.py new file mode 100644 index 000000000000..b162ed01b586 --- /dev/null +++ b/tests/caclmgrd/caclmgrd_feature_test.py @@ -0,0 +1,50 @@ +import os +import sys +import swsscommon + +from parameterized import parameterized +from sonic_py_common.general import load_module_from_source +from unittest import TestCase, mock +from pyfakefs.fake_filesystem_unittest import patchfs + +from .test_bfd_vectors import CACLMGRD_BFD_TEST_VECTOR +from tests.common.mock_configdb import MockConfigDb +from unittest.mock import MagicMock, patch + +DBCONFIG_PATH = '/var/run/redis/sonic-db/database_config.json' + +class TestFeature(TestCase): + """ + Test caclmgrd feature present + """ + def setUp(self): + swsscommon.swsscommon.ConfigDBConnector = MockConfigDb + test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + modules_path = os.path.dirname(test_path) + scripts_path = os.path.join(modules_path, "scripts") + sys.path.insert(0, modules_path) + caclmgrd_path = os.path.join(scripts_path, 'caclmgrd') + self.caclmgrd = load_module_from_source('caclmgrd', caclmgrd_path) + + @parameterized.expand(CACLMGRD_BFD_TEST_VECTOR) + @patchfs + def test_feature_present(self, test_name, test_data, fs): + if not os.path.exists(DBCONFIG_PATH): + fs.create_file(DBCONFIG_PATH) # fake database_config.json + + MockConfigDb.set_config_db(test_data["config_db"]) + + with mock.patch("caclmgrd.subprocess") as mocked_subprocess: + popen_mock = mock.Mock() + popen_attrs = test_data["popen_attributes"] + popen_mock.configure_mock(**popen_attrs) + mocked_subprocess.Popen.return_value = popen_mock + mocked_subprocess.PIPE = -1 + + call_rc = test_data["call_rc"] + mocked_subprocess.call.return_value = call_rc + + caclmgrd_daemon = self.caclmgrd.ControlPlaneAclManager("caclmgrd") + caclmgrd_daemon.update_feature_present() + self.assertTrue("bgp" in caclmgrd_daemon.feature_present) + self.assertEqual(caclmgrd_daemon.feature_present["bgp"], True) diff --git a/tests/caclmgrd/test_bfd_vectors.py b/tests/caclmgrd/test_bfd_vectors.py index 35340849bd4c..f7469376331d 100644 --- a/tests/caclmgrd/test_bfd_vectors.py +++ b/tests/caclmgrd/test_bfd_vectors.py @@ -15,6 +15,12 @@ "type": "ToRRouter", } }, + "FEATURE": { + "bgp": { + "auto_restart": "enabled", + "state": "enabled", + } + }, }, "expected_subprocess_calls": [ call("iptables -I INPUT 2 -p udp -m multiport --dports 3784,4784 -j ACCEPT", shell=True, universal_newlines=True, stdout=subprocess.PIPE), diff --git a/tests/caclmgrd/test_dhcp_vectors.py b/tests/caclmgrd/test_dhcp_vectors.py index 7ebfca22a64b..242faae34d09 100644 --- a/tests/caclmgrd/test_dhcp_vectors.py +++ b/tests/caclmgrd/test_dhcp_vectors.py @@ -14,6 +14,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "active"}), @@ -42,6 +44,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "active"}), @@ -67,6 +71,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "active"}), @@ -93,6 +99,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "active"}), @@ -117,6 +125,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "standby"}), @@ -143,6 +153,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "standby"}), @@ -167,6 +179,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "standby"}), @@ -195,6 +209,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "standby"}), @@ -220,6 +236,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "unknown"}), @@ -248,6 +266,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "unknown"}), @@ -273,6 +293,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "unknown"}), @@ -299,6 +321,8 @@ "type": "ToRRouter", } }, + "FEATURE": { + }, }, "mux_update": [ ("Ethernet4", {"state": "unknown"}),