diff --git a/scripts/db_migrator.py b/scripts/db_migrator.py index c4d4e2da9c..9a1c36a88c 100755 --- a/scripts/db_migrator.py +++ b/scripts/db_migrator.py @@ -808,6 +808,39 @@ def migrate_sflow_table(self): sflow_key = "SFLOW_SESSION_TABLE:{}".format(key) self.appDB.set(self.appDB.APPL_DB, sflow_key, 'sample_direction','rx') + def migrate_tacplus(self): + if not self.config_src_data or 'TACPLUS' not in self.config_src_data: + return + + tacplus_new = self.config_src_data['TACPLUS'] + log.log_notice('Migrate TACPLUS configuration') + + global_old = self.configDB.get_entry('TACPLUS', 'global') + if not global_old: + global_new = tacplus_new.get("global") + self.configDB.set_entry("TACPLUS", "global", global_new) + log.log_info('Migrate TACPLUS global: {}'.format(global_new)) + + def migrate_aaa(self): + if not self.config_src_data or 'AAA' not in self.config_src_data: + return + + aaa_new = self.config_src_data['AAA'] + log.log_notice('Migrate AAA configuration') + + authentication = self.configDB.get_entry('AAA', 'authentication') + if not authentication: + authentication_new = aaa_new.get("authentication") + self.configDB.set_entry("AAA", "authentication", authentication_new) + log.log_info('Migrate AAA authentication: {}'.format(authentication_new)) + + # setup per-command accounting + accounting = self.configDB.get_entry('AAA', 'accounting') + if not accounting: + accounting_new = aaa_new.get("accounting") + self.configDB.set_entry("AAA", "accounting", accounting_new) + log.log_info('Migrate AAA accounting: {}'.format(accounting_new)) + def version_unknown(self): """ version_unknown tracks all SONiC versions that doesn't have a version @@ -1235,6 +1268,9 @@ def common_migration_ops(self): # update FRR config mode based on minigraph parser on target image self.migrate_routing_config_mode() + self.migrate_tacplus() + self.migrate_aaa() + def migrate(self): version = self.get_version() log.log_info('Upgrading from version ' + version) diff --git a/tests/db_migrator_input/config_db/per_command_aaa_disable.json b/tests/db_migrator_input/config_db/per_command_aaa_disable.json new file mode 100644 index 0000000000..215e3d7fe3 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_disable.json @@ -0,0 +1,6 @@ +{ + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_disable_expected.json b/tests/db_migrator_input/config_db/per_command_aaa_disable_expected.json new file mode 100644 index 0000000000..215e3d7fe3 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_disable_expected.json @@ -0,0 +1,6 @@ +{ + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_disable_golden.json b/tests/db_migrator_input/config_db/per_command_aaa_disable_golden.json new file mode 100644 index 0000000000..abc38879b6 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_disable_golden.json @@ -0,0 +1,8 @@ +{ + "TACPLUS": { + "global": { + "auth_type": "login", + "passkey": "testpasskey" + } + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_enable.json b/tests/db_migrator_input/config_db/per_command_aaa_enable.json new file mode 100644 index 0000000000..0026e03850 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_enable.json @@ -0,0 +1,9 @@ +{ + "AAA|authentication": { + "login": "tacacs+" + }, + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_enable_expected.json b/tests/db_migrator_input/config_db/per_command_aaa_enable_expected.json new file mode 100644 index 0000000000..d39c98b7a5 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_enable_expected.json @@ -0,0 +1,12 @@ +{ + "AAA|accounting": { + "login": "tacacs+,local" + }, + "AAA|authentication": { + "login": "tacacs+" + }, + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_enable_golden.json b/tests/db_migrator_input/config_db/per_command_aaa_enable_golden.json new file mode 100644 index 0000000000..005a2fd398 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_enable_golden.json @@ -0,0 +1,19 @@ +{ + "AAA": { + "accounting": { + "login": "tacacs+,local" + }, + "authentication": { + "login": "tacacs+" + }, + "authorization": { + "login": "tacacs+" + } + }, + "TACPLUS": { + "global": { + "auth_type": "login", + "passkey": "testpasskey" + } + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_authentication.json b/tests/db_migrator_input/config_db/per_command_aaa_no_authentication.json new file mode 100644 index 0000000000..694d2f5cb3 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_authentication.json @@ -0,0 +1,9 @@ +{ + "AAA|accounting": { + "login": "tacacs+,local" + }, + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_authentication_expected.json b/tests/db_migrator_input/config_db/per_command_aaa_no_authentication_expected.json new file mode 100644 index 0000000000..d39c98b7a5 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_authentication_expected.json @@ -0,0 +1,12 @@ +{ + "AAA|accounting": { + "login": "tacacs+,local" + }, + "AAA|authentication": { + "login": "tacacs+" + }, + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_authentication_golden.json b/tests/db_migrator_input/config_db/per_command_aaa_no_authentication_golden.json new file mode 100644 index 0000000000..005a2fd398 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_authentication_golden.json @@ -0,0 +1,19 @@ +{ + "AAA": { + "accounting": { + "login": "tacacs+,local" + }, + "authentication": { + "login": "tacacs+" + }, + "authorization": { + "login": "tacacs+" + } + }, + "TACPLUS": { + "global": { + "auth_type": "login", + "passkey": "testpasskey" + } + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_change.json b/tests/db_migrator_input/config_db/per_command_aaa_no_change.json new file mode 100644 index 0000000000..518e1af6db --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_change.json @@ -0,0 +1,15 @@ +{ + "AAA|accounting": { + "login": "local" + }, + "AAA|authentication": { + "login": "tacacs+" + }, + "AAA|authorization": { + "login": "local" + }, + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_change_expected.json b/tests/db_migrator_input/config_db/per_command_aaa_no_change_expected.json new file mode 100644 index 0000000000..518e1af6db --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_change_expected.json @@ -0,0 +1,15 @@ +{ + "AAA|accounting": { + "login": "local" + }, + "AAA|authentication": { + "login": "tacacs+" + }, + "AAA|authorization": { + "login": "local" + }, + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_change_golden.json b/tests/db_migrator_input/config_db/per_command_aaa_no_change_golden.json new file mode 100644 index 0000000000..005a2fd398 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_change_golden.json @@ -0,0 +1,19 @@ +{ + "AAA": { + "accounting": { + "login": "tacacs+,local" + }, + "authentication": { + "login": "tacacs+" + }, + "authorization": { + "login": "tacacs+" + } + }, + "TACPLUS": { + "global": { + "auth_type": "login", + "passkey": "testpasskey" + } + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_passkey.json b/tests/db_migrator_input/config_db/per_command_aaa_no_passkey.json new file mode 100644 index 0000000000..6ec39507a1 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_passkey.json @@ -0,0 +1,8 @@ +{ + "AAA|authentication": { + "login": "tacacs+" + }, + "TACPLUS|global": { + "auth_type": "login" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_passkey_expected.json b/tests/db_migrator_input/config_db/per_command_aaa_no_passkey_expected.json new file mode 100644 index 0000000000..690620e52f --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_passkey_expected.json @@ -0,0 +1,11 @@ +{ + "AAA|accounting": { + "login": "tacacs+,local" + }, + "AAA|authentication": { + "login": "tacacs+" + }, + "TACPLUS|global": { + "auth_type": "login" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_passkey_golden.json b/tests/db_migrator_input/config_db/per_command_aaa_no_passkey_golden.json new file mode 100644 index 0000000000..b06af48439 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_passkey_golden.json @@ -0,0 +1,15 @@ +{ + "AAA": { + "accounting": { + "login": "tacacs+,local" + }, + "authentication": { + "login": "tacacs+" + } + }, + "TACPLUS": { + "global": { + "auth_type": "login" + } + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus.json b/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus.json new file mode 100644 index 0000000000..c45e0745ed --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus.json @@ -0,0 +1,5 @@ +{ + "AAA|authentication": { + "login": "tacacs+" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus_expected.json b/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus_expected.json new file mode 100644 index 0000000000..d39c98b7a5 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus_expected.json @@ -0,0 +1,12 @@ +{ + "AAA|accounting": { + "login": "tacacs+,local" + }, + "AAA|authentication": { + "login": "tacacs+" + }, + "TACPLUS|global": { + "auth_type": "login", + "passkey": "testpasskey" + } +} \ No newline at end of file diff --git a/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus_golden.json b/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus_golden.json new file mode 100644 index 0000000000..005a2fd398 --- /dev/null +++ b/tests/db_migrator_input/config_db/per_command_aaa_no_tacplus_golden.json @@ -0,0 +1,19 @@ +{ + "AAA": { + "accounting": { + "login": "tacacs+,local" + }, + "authentication": { + "login": "tacacs+" + }, + "authorization": { + "login": "tacacs+" + } + }, + "TACPLUS": { + "global": { + "auth_type": "login", + "passkey": "testpasskey" + } + } +} \ No newline at end of file diff --git a/tests/db_migrator_test.py b/tests/db_migrator_test.py index 21ca9148df..9a054d8924 100644 --- a/tests/db_migrator_test.py +++ b/tests/db_migrator_test.py @@ -4,6 +4,7 @@ import argparse from unittest import mock from deepdiff import DeepDiff +import json from swsscommon.swsscommon import SonicV2Connector from sonic_py_common import device_info @@ -944,3 +945,51 @@ def test_dns_nameserver_migrator_configdb(self): diff = DeepDiff(resulting_table, expected_table, ignore_order=True) assert not diff + +class TestAAAMigrator(object): + @classmethod + def setup_class(cls): + os.environ['UTILITIES_UNIT_TESTING'] = "2" + + @classmethod + def teardown_class(cls): + os.environ['UTILITIES_UNIT_TESTING'] = "0" + dbconnector.dedicated_dbs['CONFIG_DB'] = None + + def load_golden_config(self, dbmgtr, test_json): + dbmgtr.config_src_data = {} + + json_path = os.path.join(mock_db_path, 'config_db', test_json + ".json") + if os.path.exists(json_path): + with open(json_path) as f: + dbmgtr.config_src_data = json.load(f) + print("test_per_command_aaa load golden config success, config_src_data: {}".format(dbmgtr.config_src_data)) + else: + print("test_per_command_aaa load golden config failed, file {} does not exist.".format(test_json)) + + + @pytest.mark.parametrize('test_json', ['per_command_aaa_enable', + 'per_command_aaa_no_passkey', + 'per_command_aaa_disable', + 'per_command_aaa_no_change', + 'per_command_aaa_no_tacplus', + 'per_command_aaa_no_authentication']) + def test_per_command_aaa(self, test_json): + dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', test_json) + import db_migrator + dbmgtr = db_migrator.DBMigrator(None) + self.load_golden_config(dbmgtr, test_json + '_golden') + dbmgtr.migrate_tacplus() + dbmgtr.migrate_aaa() + resulting_table = dbmgtr.configDB.get_table("AAA") + + dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', test_json + '_expected') + expected_db = Db() + expected_table = expected_db.cfgdb.get_table("AAA") + + print("test_per_command_aaa: {}".format(test_json)) + print("test_per_command_aaa, resulting_table: {}".format(resulting_table)) + print("test_per_command_aaa, expected_table: {}".format(expected_table)) + + diff = DeepDiff(resulting_table, expected_table, ignore_order=True) + assert not diff