Skip to content

Commit

Permalink
Migrate AAA table in db_migrator (sonic-net#3284)
Browse files Browse the repository at this point in the history
Migrate AAA table in db_migrator

#### Why I did it
    per-command AAA need enable in warm-upgrade case

#### How I did it
    Add db_migrator code to migrate AAA table

#### How to verify it
    Pass all test case.
    Add new test case.

#### Which release branch to backport (provide reason below if selected)
    N/A

#### Description for the changelog
    Migrate AAA table in db_migrator

#### A picture of a cute animal (not mandatory but encouraged)
  • Loading branch information
liuh-80 authored and arfeigin committed Jun 16, 2024
1 parent a9e2118 commit 318dc53
Show file tree
Hide file tree
Showing 20 changed files with 304 additions and 0 deletions.
36 changes: 36 additions & 0 deletions scripts/db_migrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,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 @@ -1234,6 +1267,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"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"AAA|accounting": {
"login": "tacacs+,local"
},
"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"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"AAA|authentication": {
"login": "tacacs+"
}
}
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"
}
}
}
49 changes: 49 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, SonicDBConfig
from sonic_py_common import device_info
Expand Down Expand Up @@ -960,3 +961,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

0 comments on commit 318dc53

Please sign in to comment.