Skip to content

Commit

Permalink
[macsec] cli multi-namespace support (sonic-net#11285)
Browse files Browse the repository at this point in the history
Enable multi-asic platform support for macsec cli
  • Loading branch information
jimmyzhai authored Jul 22, 2022
1 parent ff60580 commit f01749d
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 83 deletions.
1 change: 1 addition & 0 deletions dockers/docker-macsec/cli-plugin-tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import mock_tables # lgtm [py/unused-import]
import mock_single_asic # lgtm[py/unused-import]
from unittest import mock


Expand Down
81 changes: 81 additions & 0 deletions dockers/docker-macsec/cli-plugin-tests/mock_single_asic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# MONKEY PATCH!!!
from unittest import mock

from sonic_py_common import multi_asic
from utilities_common import multi_asic as multi_asic_util

mock_intf_table = {
'': {
'eth0': {
2: [{'addr': '10.1.1.1', 'netmask': '255.255.255.0', 'broadcast': '10.1.1.1'}],
10: [{'addr': '3100::1', 'netmask': 'ffff:ffff:ffff:ffff::/64'}]
},
'Ethernet0': {
17: [{'addr': '82:fd:d1:5b:45:2f', 'broadcast': 'ff:ff:ff:ff:ff:ff'}],
2: [
{'addr': '20.1.1.1', 'netmask': '255.255.255.0', 'broadcast': '20.1.1.1'},
{'addr': '21.1.1.1', 'netmask': '255.255.255.0', 'broadcast': '21.1.1.1'}
],
10: [
{'addr': 'aa00::1', 'netmask': 'ffff:ffff:ffff:ffff::/64'},
{'addr': '2100::1', 'netmask': 'ffff:ffff:ffff:ffff::/64'},
{'addr': 'fe80::64be:a1ff:fe85:c6c4%Ethernet0', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
]
},
'PortChannel0001': {
17: [{'addr': '82:fd:d1:5b:45:2f', 'broadcast': 'ff:ff:ff:ff:ff:ff'}],
2: [{'addr': '30.1.1.1', 'netmask': '255.255.255.0', 'broadcast': '30.1.1.1'}],
10: [
{'addr': 'ab00::1', 'netmask': 'ffff:ffff:ffff:ffff::/64'},
{'addr': 'fe80::cc8d:60ff:fe08:139f%PortChannel0001', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
]
},
'Vlan100': {
17: [{'addr': '82:fd:d1:5b:45:2f', 'broadcast': 'ff:ff:ff:ff:ff:ff'}],
2: [{'addr': '40.1.1.1', 'netmask': '255.255.255.0', 'broadcast': '30.1.1.1'}],
10: [
{'addr': 'cc00::1', 'netmask': 'ffff:ffff:ffff:ffff::/64'},
{'addr': 'fe80::c029:3fff:fe41:cf56%Vlan100', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
]
},
'lo': {
2: [{'addr': '127.0.0.1', 'netmask': '255.0.0.0', 'broadcast': '127.255.255.255'}],
10: [{'addr': '::1', 'netmask':'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'}]
}
}
}


def mock_get_num_asics():
return 1

def mock_is_multi_asic():
return False

def mock_get_namespace_list(namespace=None):
return ['']


def mock_single_asic_get_ip_intf_from_ns(namespace):
interfaces = []
try:
interfaces = list(mock_intf_table[namespace].keys())
except KeyError:
pass
return interfaces


def mock_single_asic_get_ip_intf_addr_from_ns(namespace, iface):
ipaddresses = []
try:
ipaddresses = mock_intf_table[namespace][iface]
except KeyError:
pass
return ipaddresses


multi_asic.is_multi_asic = mock_is_multi_asic
multi_asic.get_num_asics = mock_get_num_asics
multi_asic.get_namespace_list = mock_get_namespace_list
multi_asic_util.multi_asic_get_ip_intf_from_ns = mock_single_asic_get_ip_intf_from_ns
multi_asic_util.multi_asic_get_ip_intf_addr_from_ns = mock_single_asic_get_ip_intf_addr_from_ns
5 changes: 4 additions & 1 deletion dockers/docker-macsec/cli-plugin-tests/mock_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ def __init__(self, db):

def get(self, macsec, name):
key = self.db.hget("COUNTERS_MACSEC_NAME_MAP", name)
return self.db.get("COUNTERS:" + key)
if key:
fvs = self.db.get("COUNTERS:" + key)
if fvs: return True, fvs
return False, ()


swsssdk.interface.DBInterface._subscribe_keyspace_notification = _subscribe_keyspace_notification
Expand Down
64 changes: 32 additions & 32 deletions dockers/docker-macsec/cli-plugin-tests/test_config_macsec.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from unittest import mock
from click.testing import CliRunner
from utilities_common.db import Db

sys.path.append('../cli/config/plugins/')
import macsec
Expand All @@ -20,14 +19,13 @@ def test_plugin_registration(self):
cli.add_command.assert_called_once_with(macsec.macsec)

def test_default_profile(self, mock_cfgdb):
cfgdb = mock_cfgdb
runner = CliRunner()
db = Db()
db.cfgdb = mock_cfgdb
result = runner.invoke(macsec.macsec.commands["profile"].commands["add"],
[profile_name, "--primary_cak=" + primary_cak,"--primary_ckn=" + primary_ckn],
obj=db)
result = runner.invoke(macsec.macsec,
["profile", "add", profile_name, "--primary_cak=" + primary_cak,"--primary_ckn=" + primary_ckn],
obj=cfgdb)
assert result.exit_code == 0
profile_table = db.cfgdb.get_entry("MACSEC_PROFILE", profile_name)
profile_table = cfgdb.get_entry("MACSEC_PROFILE", profile_name)
assert profile_table
assert profile_table["priority"] == "255"
assert profile_table["cipher_suite"] == "GCM-AES-128"
Expand All @@ -39,15 +37,14 @@ def test_default_profile(self, mock_cfgdb):
assert profile_table["send_sci"] == "true"
assert "rekey_period" not in profile_table

result = runner.invoke(macsec.macsec.commands["profile"].commands["del"], [profile_name], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "del", profile_name], obj=cfgdb)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
profile_table = db.cfgdb.get_entry("MACSEC_PROFILE", profile_name)
profile_table = cfgdb.get_entry("MACSEC_PROFILE", profile_name)
assert not profile_table

def test_macsec_valid_profile(self, mock_cfgdb):
cfgdb = mock_cfgdb
runner = CliRunner()
db = Db()
db.cfgdb = mock_cfgdb

profile_name = "test"
profile_map = {
Expand All @@ -67,9 +64,9 @@ def test_macsec_valid_profile(self, mock_cfgdb):
if v is not None:
options[-1] += "=" + str(v)

result = runner.invoke(macsec.macsec.commands["profile"].commands["add"], options, obj=db)
result = runner.invoke(macsec.macsec, ["profile", "add"] + options, obj=cfgdb)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
profile_table = db.cfgdb.get_entry("MACSEC_PROFILE", profile_name)
profile_table = cfgdb.get_entry("MACSEC_PROFILE", profile_name)
assert profile_table
assert profile_table["priority"] == str(profile_map["priority"])
assert profile_table["cipher_suite"] == profile_map["cipher_suite"]
Expand All @@ -87,62 +84,65 @@ def test_macsec_valid_profile(self, mock_cfgdb):
assert profile_table["rekey_period"] == str(profile_map["rekey_period"])

def test_macsec_invalid_profile(self, mock_cfgdb):
cfgdb = mock_cfgdb
runner = CliRunner()
db = Db()
db.cfgdb = mock_cfgdb

# Loss primary cak and primary ckn
result = runner.invoke(macsec.macsec.commands["profile"].commands["add"], ["test"], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "add", "test"], obj=cfgdb)
assert result.exit_code != 0

# Invalid primary cak
result = runner.invoke(macsec.macsec.commands["profile"].commands["add"], ["test", "--primary_cak=abcdfghjk90123456789012345678912","--primary_ckn=01234567890123456789012345678912", "--cipher_suite=GCM-AES-128"], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "add", "test",
"--primary_cak=abcdfghjk90123456789012345678912","--primary_ckn=01234567890123456789012345678912",
"--cipher_suite=GCM-AES-128"], obj=cfgdb)
assert result.exit_code != 0

# Invalid primary cak length
result = runner.invoke(macsec.macsec.commands["profile"].commands["add"], ["test", "--primary_cak=01234567890123456789012345678912","--primary_ckn=01234567890123456789012345678912", "--cipher_suite=GCM-AES-256"], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "add", "test",
"--primary_cak=01234567890123456789012345678912","--primary_ckn=01234567890123456789012345678912",
"--cipher_suite=GCM-AES-256"], obj=cfgdb)
assert result.exit_code != 0


def test_macsec_port(self, mock_cfgdb):
cfgdb = mock_cfgdb
runner = CliRunner()
db = Db()
db.cfgdb = mock_cfgdb

result = runner.invoke(macsec.macsec.commands["profile"].commands["add"], ["test", "--primary_cak=01234567890123456789012345678912","--primary_ckn=01234567890123456789012345678912"], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "add", "test",
"--primary_cak=01234567890123456789012345678912","--primary_ckn=01234567890123456789012345678912"],
obj=cfgdb)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = runner.invoke(macsec.macsec.commands["port"].commands["add"], ["Ethernet0", "test"], obj=db)
result = runner.invoke(macsec.macsec, ["port", "add", "Ethernet0", "test"], obj=cfgdb)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
port_table = db.cfgdb.get_entry("PORT", "Ethernet0")
port_table = cfgdb.get_entry("PORT", "Ethernet0")
assert port_table
assert port_table["macsec"] == "test"
assert port_table["admin_status"] == "up"

result = runner.invoke(macsec.macsec.commands["profile"].commands["del"], ["test"], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "del", "test"], obj=cfgdb)
assert result.exit_code != 0

result = runner.invoke(macsec.macsec.commands["port"].commands["del"], ["Ethernet0"], obj=db)
result = runner.invoke(macsec.macsec, ["port", "del", "Ethernet0"], obj=cfgdb)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
port_table = db.cfgdb.get_entry("PORT", "Ethernet0")
port_table = cfgdb.get_entry("PORT", "Ethernet0")
assert "macsec" not in port_table or not port_table["macsec"]
assert port_table["admin_status"] == "up"


def test_macsec_invalid_operation(self, mock_cfgdb):
cfgdb = mock_cfgdb
runner = CliRunner()
db = Db()
db.cfgdb = mock_cfgdb

# Enable nonexisted profile
result = runner.invoke(macsec.macsec.commands["port"].commands["add"], ["Ethernet0", "test"], obj=db)
result = runner.invoke(macsec.macsec, ["port", "add", "Ethernet0", "test"], obj=cfgdb)
assert result.exit_code != 0

# Delete nonexisted profile
result = runner.invoke(macsec.macsec.commands["profile"].commands["del"], ["test"], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "del", "test"], obj=cfgdb)
assert result.exit_code != 0

result = runner.invoke(macsec.macsec.commands["profile"].commands["add"], ["test", "--primary_cak=01234567890123456789012345678912","--primary_ckn=01234567890123456789012345678912"], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "add", "test", "--primary_cak=01234567890123456789012345678912","--primary_ckn=01234567890123456789012345678912"], obj=cfgdb)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
# Repeat add profile
result = runner.invoke(macsec.macsec.commands["profile"].commands["add"], ["test", "--primary_cak=01234567890123456789012345678912","--primary_ckn=01234567890123456789012345678912"], obj=db)
result = runner.invoke(macsec.macsec, ["profile", "add", "test", "--primary_cak=01234567890123456789012345678912","--primary_ckn=01234567890123456789012345678912"], obj=cfgdb)
assert result.exit_code != 0
Loading

0 comments on commit f01749d

Please sign in to comment.