Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate AAA table in db_migrator #3284

Merged
merged 13 commits into from
Apr 29, 2024
36 changes: 36 additions & 0 deletions scripts/db_migrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"TACPLUS|global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"TACPLUS|global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"TACPLUS": {
"global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
}
9 changes: 9 additions & 0 deletions tests/db_migrator_input/config_db/per_command_aaa_enable.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"AAA|authentication": {
"login": "tacacs+"
},
"TACPLUS|global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"AAA|accounting": {
"login": "tacacs+,local"
},
"AAA|authentication": {
"login": "tacacs+"
},
"TACPLUS|global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"AAA": {
"accounting": {
"login": "tacacs+,local"
},
"authentication": {
"login": "tacacs+"
},
"authorization": {
"login": "tacacs+"
}
},
"TACPLUS": {
"global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
}
15 changes: 15 additions & 0 deletions tests/db_migrator_input/config_db/per_command_aaa_no_change.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"AAA|accounting": {
"login": "local"
},
"AAA|authentication": {
"login": "tacacs+"
},
"AAA|authorization": {
"login": "local"
},
"TACPLUS|global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"AAA|accounting": {
"login": "local"
},
"AAA|authentication": {
"login": "tacacs+"
},
"AAA|authorization": {
"login": "local"
},
"TACPLUS|global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"AAA": {
"accounting": {
"login": "tacacs+,local"
},
"authentication": {
"login": "tacacs+"
},
"authorization": {
"login": "tacacs+"
}
},
"TACPLUS": {
"global": {
"auth_type": "login",
"passkey": "testpasskey"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"AAA|authentication": {
"login": "tacacs+"
},
"TACPLUS|global": {
"auth_type": "login"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"AAA|accounting": {
"login": "tacacs+,local"
},
"AAA|authentication": {
"login": "tacacs+"
},
"TACPLUS|global": {
"auth_type": "login"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"AAA": {
"accounting": {
"login": "tacacs+,local"
},
"authentication": {
"login": "tacacs+"
}
},
"TACPLUS": {
"global": {
"auth_type": "login"
}
}
}
47 changes: 47 additions & 0 deletions tests/db_migrator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -944,3 +945,49 @@ 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'])
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
Loading