Skip to content

Commit 89bb87a

Browse files
authored
Add YANG validation for config reload if file is given (#3576)
What I did Add constraint for YANG when config reload, which is already enabled in load_minigraph How I did it Check YANG vaidation for the config How to verify it Unit test
1 parent 4a6d121 commit 89bb87a

File tree

2 files changed

+49
-9
lines changed

2 files changed

+49
-9
lines changed

config/main.py

+21-9
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,19 @@ def multiasic_write_to_db(filename, load_sysinfo):
13721372
migrate_db_to_lastest(ns)
13731373

13741374

1375+
def config_file_yang_validation(filename):
1376+
config_to_check = read_json_file(filename)
1377+
sy = sonic_yang.SonicYang(YANG_DIR)
1378+
sy.loadYangModel()
1379+
try:
1380+
sy.loadData(configdbJson=config_to_check)
1381+
sy.validate_data_tree()
1382+
except sonic_yang.SonicYangException as e:
1383+
click.secho("{} fails YANG validation! Error: {}".format(filename, str(e)),
1384+
fg='magenta')
1385+
raise click.Abort()
1386+
1387+
13751388
# This is our main entrypoint - the main 'config' command
13761389
@click.group(cls=clicommon.AbbreviationGroup, context_settings=CONTEXT_SETTINGS)
13771390
@click.pass_context
@@ -1810,6 +1823,13 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
18101823
click.echo("Input {} config file(s) separated by comma for multiple files ".format(num_cfg_file))
18111824
return
18121825

1826+
if filename is not None:
1827+
if multi_asic.is_multi_asic():
1828+
# Multiasic has not 100% fully validated. Thus pass here.
1829+
pass
1830+
else:
1831+
config_file_yang_validation(filename)
1832+
18131833
#Stop services before config push
18141834
if not no_service_restart:
18151835
log.log_notice("'reload' stopping services...")
@@ -2000,15 +2020,7 @@ def load_minigraph(db, no_service_restart, traffic_shift_away, override_config,
20002020
# Multiasic has not 100% fully validated. Thus pass here.
20012021
pass
20022022
else:
2003-
sy = sonic_yang.SonicYang(YANG_DIR)
2004-
sy.loadYangModel()
2005-
try:
2006-
sy.loadData(configdbJson=config_to_check)
2007-
sy.validate_data_tree()
2008-
except sonic_yang.SonicYangException as e:
2009-
click.secho("{} fails YANG validation! Error: {}".format(golden_config_path, str(e)),
2010-
fg='magenta')
2011-
raise click.Abort()
2023+
config_file_yang_validation(golden_config_path)
20122024

20132025
# Dependency check golden config json
20142026
if multi_asic.is_multi_asic():

tests/config_test.py

+28
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,34 @@ def test_reload_yang_config(self, get_cmd_module,
13841384
assert "\n".join([l.rstrip() for l in result.output.split('\n')]) \
13851385
== RELOAD_YANG_CFG_OUTPUT.format(config.SYSTEM_RELOAD_LOCK)
13861386

1387+
def test_reload_config_fails_yang_validation(self, get_cmd_module, setup_single_broadcom_asic):
1388+
with open(self.dummy_cfg_file, 'w') as f:
1389+
device_metadata = {
1390+
"DEVICE_METADATA": {
1391+
"localhost": {
1392+
"invalid_hwsku": "some_hwsku"
1393+
}
1394+
}
1395+
}
1396+
f.write(json.dumps(device_metadata))
1397+
1398+
with mock.patch(
1399+
"utilities_common.cli.run_command",
1400+
mock.MagicMock(side_effect=mock_run_command_side_effect)
1401+
):
1402+
(config, _) = get_cmd_module
1403+
runner = CliRunner()
1404+
1405+
result = runner.invoke(
1406+
config.config.commands["reload"],
1407+
[self.dummy_cfg_file, '-y', '-f'])
1408+
1409+
print(result.exit_code)
1410+
print(result.output)
1411+
traceback.print_tb(result.exc_info[2])
1412+
assert result.exit_code != 0
1413+
assert "fails YANG validation! Error" in result.output
1414+
13871415
@classmethod
13881416
def teardown_class(cls):
13891417
os.environ['UTILITIES_UNIT_TESTING'] = "0"

0 commit comments

Comments
 (0)