Skip to content

Commit

Permalink
YANG Validation for ConfigDB Updates: RADIUS_SERVER (#2604)
Browse files Browse the repository at this point in the history
#### What I did
Add YANG validation using GCU for writes to RADIUS_SERVER table in ConfigDB
#### How I did it
Using same method as https://github.com/sonic-net/sonic-utilities/pull/2190/files, extend to RADIUS table
#### How to verify it
verified testing on virtual switch CLI, unit tests
  • Loading branch information
isabelmsft authored Jan 17, 2023
1 parent c2d746d commit 8703773
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 19 deletions.
52 changes: 33 additions & 19 deletions config/aaa.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from swsscommon.swsscommon import ConfigDBConnector
from .validated_config_db_connector import ValidatedConfigDBConnector
from jsonpatch import JsonPatchConflict
from jsonpointer import JsonPointerException
import utilities_common.cli as clicommon

ADHOC_VALIDATION = True
Expand Down Expand Up @@ -498,15 +499,16 @@ def statistics(option):
def add(address, retransmit, timeout, key, auth_type, auth_port, pri, use_mgmt_vrf, source_interface):
"""Specify a RADIUS server"""

if key:
if len(key) > RADIUS_PASSKEY_MAX_LEN:
click.echo('--key: Maximum of %d chars can be configured' % RADIUS_PASSKEY_MAX_LEN)
return
elif not is_secret(key):
click.echo('--key: ' + VALID_CHARS_MSG)
return
if ADHOC_VALIDATION:
if key:
if len(key) > RADIUS_PASSKEY_MAX_LEN:
click.echo('--key: Maximum of %d chars can be configured' % RADIUS_PASSKEY_MAX_LEN)
return
elif not is_secret(key):
click.echo('--key: ' + VALID_CHARS_MSG)
return

config_db = ConfigDBConnector()
config_db = ValidatedConfigDBConnector(ConfigDBConnector())
config_db.connect()
old_data = config_db.get_table('RADIUS_SERVER')
if address in old_data :
Expand All @@ -529,16 +531,24 @@ def add(address, retransmit, timeout, key, auth_type, auth_port, pri, use_mgmt_v
data['passkey'] = key
if use_mgmt_vrf :
data['vrf'] = "mgmt"
if source_interface :
if (source_interface.startswith("Ethernet") or \
source_interface.startswith("PortChannel") or \
source_interface.startswith("Vlan") or \
source_interface.startswith("Loopback") or \
source_interface == "eth0"):
if ADHOC_VALIDATION:
if source_interface :
if (source_interface.startswith("Ethernet") or \
source_interface.startswith("PortChannel") or \
source_interface.startswith("Vlan") or \
source_interface.startswith("Loopback") or \
source_interface == "eth0"):
data['src_intf'] = source_interface
else:
click.echo('Not supported interface name (valid interface name: Etherent<id>/PortChannel<id>/Vlan<id>/Loopback<id>/eth0)')
else:
if source_interface:
data['src_intf'] = source_interface
else:
click.echo('Not supported interface name (valid interface name: Etherent<id>/PortChannel<id>/Vlan<id>/Loopback<id>/eth0)')
config_db.set_entry('RADIUS_SERVER', address, data)
try:
config_db.set_entry('RADIUS_SERVER', address, data)
except ValueError as e:
ctx = click.get_current_context()
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
radius.add_command(add)


Expand All @@ -549,7 +559,11 @@ def add(address, retransmit, timeout, key, auth_type, auth_port, pri, use_mgmt_v
def delete(address):
"""Delete a RADIUS server"""

config_db = ConfigDBConnector()
config_db = ValidatedConfigDBConnector(ConfigDBConnector())
config_db.connect()
config_db.set_entry('RADIUS_SERVER', address, None)
try:
config_db.set_entry('RADIUS_SERVER', address, None)
except (JsonPointerException, JsonPatchConflict) as e:
ctx = click.get_current_context()
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
radius.add_command(delete)
25 changes: 25 additions & 0 deletions tests/radius_test.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import imp
import os
import sys
import mock
import jsonpatch

from click.testing import CliRunner
from utilities_common.db import Db
from mock import patch
from jsonpointer import JsonPointerException

import config.main as config
import config.aaa as aaa
import show.main as show

test_path = os.path.dirname(os.path.abspath(__file__))
Expand Down Expand Up @@ -192,3 +197,23 @@ def test_config_radius_authtype(self, get_cmd_module):
assert result.exit_code == 0
assert result.output == show_radius_default_output

@patch("validated_config_db_connector.device_info.is_yang_config_validation_enabled", mock.Mock(return_value=True))
@patch("config.validated_config_db_connector.ValidatedConfigDBConnector.validated_set_entry", mock.Mock(side_effect=ValueError))
def test_config_radius_server_invalidkey_yang_validation(self):
aaa.ADHOC_VALIDATION = False
runner = CliRunner()
result = runner.invoke(config.config.commands["radius"],\
["add", "10.10.10.10", "-r", "1", "-t", "3",\
"-k", "comma,invalid", "-s", "eth0"])
print(result.output)
assert "Invalid ConfigDB. Error" in result.output

@patch("validated_config_db_connector.device_info.is_yang_config_validation_enabled", mock.Mock(return_value=True))
@patch("config.validated_config_db_connector.ValidatedConfigDBConnector.validated_set_entry", mock.Mock(side_effect=JsonPointerException))
def test_config_radius_server_invalid_delete_yang_validation(self):
aaa.ADHOC_VALIDATION = False
runner = CliRunner()
result = runner.invoke(config.config.commands["radius"],\
["delete", "10.10.10.x"])
print(result.output)
assert "Invalid ConfigDB. Error" in result.output

0 comments on commit 8703773

Please sign in to comment.