def test_loopback_events(self):
     MockConfigDb.set_config_db(HOSTCFG_DAEMON_CFG_DB)
     MockConfigDb.event_queue = [('NTP', 'global'),
                                 ('NTP_SERVER', '0.debian.pool.ntp.org'),
                                 ('LOOPBACK_INTERFACE',
                                  'Loopback0|10.184.8.233/32')]
     daemon = hostcfgd.HostConfigDaemon()
     daemon.register_callbacks()
     with mock.patch('hostcfgd.subprocess') as mocked_subprocess:
         popen_mock = mock.Mock()
         attrs = {'communicate.return_value': ('output', 'error')}
         popen_mock.configure_mock(**attrs)
         mocked_subprocess.Popen.return_value = popen_mock
         try:
             daemon.start()
         except TimeoutError:
             pass
         expected = [
             call('systemctl restart ntp-config', shell=True),
             call(
                 'iptables -t mangle --append PREROUTING -p tcp --tcp-flags SYN SYN -d 10.184.8.233 -j TCPMSS --set-mss 1460',
                 shell=True),
             call(
                 'iptables -t mangle --append POSTROUTING -p tcp --tcp-flags SYN SYN -s 10.184.8.233 -j TCPMSS --set-mss 1460',
                 shell=True)
         ]
         mocked_subprocess.check_call.assert_has_calls(expected,
                                                       any_order=True)
    def test_caclmgrd_dhcp(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

            call_rc = test_data["call_rc"]
            mocked_subprocess.call.return_value = call_rc

            mark = test_data["mark"]

            caclmgrd_daemon = caclmgrd.ControlPlaneAclManager("caclmgrd")
            mux_update = test_data["mux_update"]

            for key, data in mux_update:
                caclmgrd_daemon.update_dhcp_acl(key, '', data, mark)

            mocked_subprocess.call.assert_has_calls(
                test_data["expected_subprocess_calls"], any_order=False)
Example #3
0
    def test_hostcfgd_radius(self, test_name, test_data):
        """
            Test RADIUS hostcfd daemon initialization

            Args:
                test_name(str): test name
                test_data(dict): test data which contains initial Config Db tables, and expected results

            Returns:
                None
        """

        t_path = templates_path
        op_path = output_path + "/" + test_name
        sop_path = sample_output_path + "/" + test_name

        hostcfgd.PAM_AUTH_CONF_TEMPLATE = t_path + "/common-auth-sonic.j2"
        hostcfgd.NSS_TACPLUS_CONF_TEMPLATE = t_path + "/tacplus_nss.conf.j2"
        hostcfgd.NSS_RADIUS_CONF_TEMPLATE = t_path + "/radius_nss.conf.j2"
        hostcfgd.PAM_RADIUS_AUTH_CONF_TEMPLATE = t_path + "/pam_radius_auth.conf.j2"
        hostcfgd.PAM_AUTH_CONF = op_path + "/common-auth-sonic"
        hostcfgd.NSS_TACPLUS_CONF = op_path + "/tacplus_nss.conf"
        hostcfgd.NSS_RADIUS_CONF = op_path + "/radius_nss.conf"
        hostcfgd.NSS_CONF = op_path + "/nsswitch.conf"
        hostcfgd.ETC_PAMD_SSHD = op_path + "/sshd"
        hostcfgd.ETC_PAMD_LOGIN = op_path + "/login"
        hostcfgd.RADIUS_PAM_AUTH_CONF_DIR = op_path + "/"

        shutil.rmtree(op_path, ignore_errors=True)
        os.mkdir(op_path)

        shutil.copyfile(sop_path + "/sshd.old", op_path + "/sshd")
        shutil.copyfile(sop_path + "/login.old", op_path + "/login")

        MockConfigDb.set_config_db(test_data["config_db"])
        host_config_daemon = hostcfgd.HostConfigDaemon()

        aaa = host_config_daemon.config_db.get_table('AAA')

        try:
            radius_global = host_config_daemon.config_db.get_table('RADIUS')
        except:
            radius_global = []
        try:
            radius_server = \
                host_config_daemon.config_db.get_table('RADIUS_SERVER')
        except:
            radius_server = []

        host_config_daemon.aaacfg.load(aaa, [], [], radius_global,
                                       radius_server)
        dcmp = filecmp.dircmp(sop_path, op_path)
        diff_output = ""
        for name in dcmp.diff_files:
            diff_output += \
                "Diff: file: {} expected: {} output: {}\n".format(\
                    name, dcmp.left, dcmp.right)
            diff_output += self.run_diff( dcmp.left + "/" + name,\
                dcmp.right + "/" + name)
        self.assertTrue(len(diff_output) == 0, diff_output)
Example #4
0
    def test_hostcfgd(self, test_name, test_data, fs):
        """
            Test hostcfd daemon initialization

            Args:
                test_name(str): test name
                test_data(dict): test data which contains initial Config Db tables, and expected results

            Returns:
                None
        """
        fs.add_real_paths(
            swsscommon_package.__path__
        )  # add real path of swsscommon for database_config.json
        fs.create_dir(hostcfgd.FeatureHandler.SYSTEMD_SYSTEM_DIR)
        MockConfigDb.set_config_db(test_data["config_db"])
        with mock.patch("hostcfgd.subprocess") as mocked_subprocess:
            popen_mock = mock.Mock()
            attrs = test_data["popen_attributes"]
            popen_mock.configure_mock(**attrs)
            mocked_subprocess.Popen.return_value = popen_mock

            host_config_daemon = hostcfgd.HostConfigDaemon()
            host_config_daemon.feature_handler.update_all_features_config()
            assert self.__verify_table(
                MockConfigDb.get_config_db()["FEATURE"],
                test_data["expected_config_db"]["FEATURE"]
            ), "Test failed for test data: {0}".format(test_data)
            mocked_subprocess.check_call.assert_has_calls(
                test_data["expected_subprocess_calls"], any_order=True)

            self.__verify_fs(test_data["config_db"]["FEATURE"])
    def check_config(self, test_name, test_data, config_name):
        t_path = templates_path
        op_path = output_path + "/" + test_name + "_" + config_name
        sop_path = sample_output_path + "/" + test_name + "_" + config_name

        hostcfgd.PAM_AUTH_CONF_TEMPLATE = t_path + "/common-auth-sonic.j2"
        hostcfgd.NSS_TACPLUS_CONF_TEMPLATE = t_path + "/tacplus_nss.conf.j2"
        hostcfgd.NSS_RADIUS_CONF_TEMPLATE = t_path + "/radius_nss.conf.j2"
        hostcfgd.PAM_RADIUS_AUTH_CONF_TEMPLATE = t_path + "/pam_radius_auth.conf.j2"
        hostcfgd.PAM_AUTH_CONF = op_path + "/common-auth-sonic"
        hostcfgd.NSS_TACPLUS_CONF = op_path + "/tacplus_nss.conf"
        hostcfgd.NSS_RADIUS_CONF = op_path + "/radius_nss.conf"
        hostcfgd.NSS_CONF = op_path + "/nsswitch.conf"
        hostcfgd.ETC_PAMD_SSHD = op_path + "/sshd"
        hostcfgd.ETC_PAMD_LOGIN = op_path + "/login"
        hostcfgd.RADIUS_PAM_AUTH_CONF_DIR = op_path + "/"

        shutil.rmtree(op_path, ignore_errors=True)
        os.mkdir(op_path)

        shutil.copyfile(sop_path + "/sshd.old", op_path + "/sshd")
        shutil.copyfile(sop_path + "/login.old", op_path + "/login")

        MockConfigDb.set_config_db(test_data[config_name])
        host_config_daemon = hostcfgd.HostConfigDaemon()

        aaa = host_config_daemon.config_db.get_table('AAA')

        try:
            tacacs_global = host_config_daemon.config_db.get_table('TACPLUS')
        except:
            tacacs_global = []
        try:
            tacacs_server = \
                host_config_daemon.config_db.get_table('TACPLUS_SERVER')
        except:
            tacacs_server = []

        host_config_daemon.aaacfg.load(aaa, tacacs_global, tacacs_server, [],
                                       [])
        dcmp = filecmp.dircmp(sop_path, op_path)
        diff_output = ""
        for name in dcmp.diff_files:
            diff_output += \
                "Diff: file: {} expected: {} output: {}\n".format(\
                    name, dcmp.left, dcmp.right)
            diff_output += self.run_diff( dcmp.left + "/" + name,\
                dcmp.right + "/" + name)
        self.assertTrue(len(diff_output) == 0, diff_output)
Example #6
0
    def test_sync_state_field(self, test_scenario_name, config_data, fs):
        """Tests the method `sync_state_field(...)` of `FeatureHandler` class.

        Args:
            test_secnario_name: A string indicates different testing scenario.
            config_data: A dictionary contains initial `CONFIG_DB` tables and expected results.

        Returns:
            Boolean value indicates whether test will pass or not.
        """
        # add real path of sesscommon for database_config.json
        fs.add_real_paths(swsscommon_package.__path__)
        fs.create_dir(hostcfgd.FeatureHandler.SYSTEMD_SYSTEM_DIR)

        MockConfigDb.set_config_db(config_data['config_db'])
        feature_state_table_mock = mock.Mock()
        with mock.patch('hostcfgd.subprocess') as mocked_subprocess:
            popen_mock = mock.Mock()
            attrs = config_data['popen_attributes']
            popen_mock.configure_mock(**attrs)
            mocked_subprocess.Popen.return_value = popen_mock

            device_config = {}
            device_config['DEVICE_METADATA'] = MockConfigDb.CONFIG_DB[
                'DEVICE_METADATA']
            feature_handler = hostcfgd.FeatureHandler(
                MockConfigDb(), feature_state_table_mock, device_config)

            feature_table = MockConfigDb.CONFIG_DB['FEATURE']
            feature_handler.sync_state_field(feature_table)

            is_any_difference = self.checks_config_table(
                MockConfigDb.get_config_db()['FEATURE'],
                config_data['expected_config_db']['FEATURE'])
            assert is_any_difference, "'FEATURE' table in 'CONFIG_DB' is modified unexpectedly!"

            feature_table_state_db_calls = self.get_state_db_set_calls(
                feature_table)

            self.checks_systemd_config_file(
                config_data['config_db']['FEATURE'])
            mocked_subprocess.check_call.assert_has_calls(
                config_data['enable_feature_subprocess_calls'], any_order=True)
            mocked_subprocess.check_call.assert_has_calls(
                config_data['daemon_reload_subprocess_call'], any_order=True)
            feature_state_table_mock.set.assert_has_calls(
                feature_table_state_db_calls)
            self.checks_systemd_config_file(
                config_data['config_db']['FEATURE'])
    def test_hostcfgd_feature_handler(self, test_name, test_data, fs):
        """
            Test feature config capability in the hostcfd

            Args:
                test_name(str): test name
                test_data(dict): test data which contains initial Config Db tables, and expected results

            Returns:
                None
        """
        fs.add_real_paths(
            swsscommon_package.__path__
        )  # add real path of swsscommon for database_config.json
        fs.create_dir(hostcfgd.FeatureHandler.SYSTEMD_SYSTEM_DIR)
        MockConfigDb.set_config_db(test_data['config_db'])
        feature_state_table_mock = mock.Mock()
        with mock.patch('hostcfgd.subprocess') as mocked_subprocess:
            popen_mock = mock.Mock()
            attrs = test_data['popen_attributes']
            popen_mock.configure_mock(**attrs)
            mocked_subprocess.Popen.return_value = popen_mock

            # Initialize Feature Handler
            device_config = {}
            device_config['DEVICE_METADATA'] = MockConfigDb.CONFIG_DB[
                'DEVICE_METADATA']
            feature_handler = hostcfgd.FeatureHandler(
                MockConfigDb(), feature_state_table_mock, device_config)

            # sync the state field and Handle Feature Updates
            features = MockConfigDb.CONFIG_DB['FEATURE']
            feature_handler.sync_state_field(features)
            for key, fvs in features.items():
                feature_handler.handle(key, 'SET', fvs)

            # Verify if the updates are properly updated
            assert self.__verify_table(
                MockConfigDb.get_config_db()['FEATURE'],
                feature_state_table_mock,
                test_data['expected_config_db']['FEATURE']
            ), 'Test failed for test data: {0}'.format(test_data)
            mocked_subprocess.check_call.assert_has_calls(
                test_data['expected_subprocess_calls'], any_order=True)

            self.__verify_fs(test_data['config_db']['FEATURE'])
    def test_caclmgrd_bfd(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.allow_bfd_protocol('')
            mocked_subprocess.Popen.assert_has_calls(
                test_data["expected_subprocess_calls"], any_order=True)
 def test_kdump_event(self):
     MockConfigDb.set_config_db(HOSTCFG_DAEMON_CFG_DB)
     daemon = hostcfgd.HostConfigDaemon()
     daemon.register_callbacks()
     MockConfigDb.event_queue = [('KDUMP', 'config')]
     with mock.patch('hostcfgd.subprocess') as mocked_subprocess:
         popen_mock = mock.Mock()
         attrs = {'communicate.return_value': ('output', 'error')}
         popen_mock.configure_mock(**attrs)
         mocked_subprocess.Popen.return_value = popen_mock
         try:
             daemon.start()
         except TimeoutError:
             pass
         expected = [
             call('sonic-kdump-config --disable', shell=True),
             call('sonic-kdump-config --num_dumps 3', shell=True),
             call(
                 'sonic-kdump-config --memory 0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M',
                 shell=True)
         ]
         mocked_subprocess.check_call.assert_has_calls(expected,
                                                       any_order=True)
 def setUp(self):
     MockConfigDb.set_config_db(HOSTCFG_DAEMON_CFG_DB)
Example #11
0
    def check_config(self, test_name, test_data, config_name):
        t_path = templates_path
        op_path = output_path + "/" + test_name + "_" + config_name
        sop_path = sample_output_path + "/" + test_name + "_" + config_name
        sop_path_common = sample_output_path + "/" + test_name

        hostcfgd.PAM_PASSWORD_CONF_TEMPLATE = t_path + "/common-password.j2"
        hostcfgd.PAM_AUTH_CONF_TEMPLATE = t_path + "/common-auth-sonic.j2"
        hostcfgd.NSS_TACPLUS_CONF_TEMPLATE = t_path + "/tacplus_nss.conf.j2"
        hostcfgd.NSS_RADIUS_CONF_TEMPLATE = t_path + "/radius_nss.conf.j2"
        hostcfgd.PAM_RADIUS_AUTH_CONF_TEMPLATE = t_path + "/pam_radius_auth.conf.j2"
        hostcfgd.PAM_PASSWORD_CONF = op_path + "/common-password"
        hostcfgd.ETC_LOGIN_DEF = op_path + "/login.defs"
        hostcfgd.PAM_AUTH_CONF = op_path + "/common-auth-sonic"
        hostcfgd.NSS_TACPLUS_CONF = op_path + "/tacplus_nss.conf"
        hostcfgd.NSS_RADIUS_CONF = op_path + "/radius_nss.conf"
        hostcfgd.NSS_CONF = op_path + "/nsswitch.conf"
        hostcfgd.ETC_PAMD_SSHD = op_path + "/sshd"
        hostcfgd.ETC_PAMD_LOGIN = op_path + "/login"
        hostcfgd.RADIUS_PAM_AUTH_CONF_DIR = op_path + "/"

        shutil.rmtree(op_path, ignore_errors=True)
        os.mkdir(op_path)

        shutil.copyfile(sop_path_common + "/login.defs.old",
                        op_path + "/login.defs")
        MockConfigDb.set_config_db(test_data[config_name])
        host_config_daemon = hostcfgd.HostConfigDaemon()

        try:
            passwh_table = host_config_daemon.config_db.get_table(
                'PASSW_HARDENING')
        except Exception as e:
            syslog.syslog(
                syslog.LOG_ERR,
                "failed: get_table 'PASSW_HARDENING', exception={}".format(e))
            passwh_table = []

        host_config_daemon.passwcfg.load(passwh_table)

        diff_output = ""
        files_to_compare = ['common-password']

        # check output files exists
        for name in files_to_compare:
            if not os.path.isfile(sop_path + "/" + name):
                raise ValueError('filename: %s not exit' %
                                 (sop_path + "/" + name))
            if not os.path.isfile(op_path + "/" + name):
                raise ValueError('filename: %s not exit' %
                                 (op_path + "/" + name))

        # deep comparison
        match, mismatch, errors = filecmp.cmpfiles(sop_path,
                                                   op_path,
                                                   files_to_compare,
                                                   shallow=False)

        if not match:
            for name in files_to_compare:
                diff_output += self.run_diff( sop_path + "/" + name,\
                    op_path + "/" + name).decode('utf-8')

        self.assertTrue(len(diff_output) == 0, diff_output)

        # compare age data in login.def file.
        out_passw_age_days = self.get_passw_days(op_path + "/login.defs",
                                                 'MAX_DAYS')
        sout_passw_age_days = self.get_passw_days(sop_path + "/login.defs",
                                                  'MAX_DAYS')
        out_passw_age_warn_days = self.get_passw_days(op_path + "/login.defs",
                                                      'WARN_DAYS')
        sout_passw_age_warn_days = self.get_passw_days(
            sop_path + "/login.defs", 'WARN_DAYS')

        self.assertEqual(out_passw_age_days, sout_passw_age_days)
        self.assertEqual(out_passw_age_warn_days, sout_passw_age_warn_days)