Skip to content

Commit

Permalink
Exit early if YANG validation fails in Golden Config
Browse files Browse the repository at this point in the history
  • Loading branch information
wen587 committed Aug 16, 2024
1 parent 317e649 commit 16481df
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 105 deletions.
17 changes: 16 additions & 1 deletion config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1983,8 +1983,23 @@ def load_minigraph(db, no_service_restart, traffic_shift_away, override_config,
fg='magenta')
raise click.Abort()

# Dependency check golden config json
cfgdb_clients = db.cfgdb_clients
# Pick the host config in case of multi-asic
config_db = cfgdb_clients[DEFAULT_NAMESPACE]

cm = None
try:
cm = ConfigMgmt(configdb=config_db)
cm.validateConfigData()
except Exception as ex:
log.log_warning("The existing config fails YANG validation. Alerting: {}".format(ex))

config_to_check = read_json_file(golden_config_path)
# YANG validation for golden config json
if cm:
validate_config_by_cm(cm, config_to_check, "golden_config")

# Dependency check golden config json
if multi_asic.is_multi_asic():
host_config = config_to_check.get('localhost', {})
else:
Expand Down
89 changes: 0 additions & 89 deletions tests/config_override_input/golden_input_yang_failure.json

This file was deleted.

24 changes: 24 additions & 0 deletions tests/config_override_input/partial_config_override.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,30 @@
"stage": "ingress",
"type": "CTRLPLANE"
}
},
"PORT": {
"Ethernet4": {
"admin_status": "up",
"alias": "fortyGigE0/4",
"description": "Servers0:eth0",
"index": "1",
"lanes": "29,30,31,32",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
},
"Ethernet8": {
"admin_status": "up",
"alias": "fortyGigE0/8",
"description": "Servers1:eth0",
"index": "2",
"lanes": "33,34,35,36",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
}
}
},
"expected_config": {
Expand Down
12 changes: 0 additions & 12 deletions tests/config_override_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
EMPTY_TABLE_REMOVAL = os.path.join(DATA_DIR, "empty_table_removal.json")
AAA_YANG_HARD_CHECK = os.path.join(DATA_DIR, "aaa_yang_hard_check.json")
RUNNING_CONFIG_YANG_FAILURE = os.path.join(DATA_DIR, "running_config_yang_failure.json")
GOLDEN_INPUT_YANG_FAILURE = os.path.join(DATA_DIR, "golden_input_yang_failure.json")
FINAL_CONFIG_YANG_FAILURE = os.path.join(DATA_DIR, "final_config_yang_failure.json")
MULTI_ASIC_MACSEC_OV = os.path.join(DATA_DIR, "multi_asic_macsec_ov.json")
MULTI_ASIC_FEATURE_RM = os.path.join(DATA_DIR, "multi_asic_feature_rm.json")
Expand Down Expand Up @@ -233,17 +232,6 @@ def is_yang_config_validation_enabled_side_effect(filename):
self.check_yang_verification_failure(
db, config, read_data['running_config'], read_data['golden_config'], "running config")

def test_golden_input_yang_failure(self):
def is_yang_config_validation_enabled_side_effect(filename):
return True
db = Db()
with open(GOLDEN_INPUT_YANG_FAILURE, "r") as f:
read_data = json.load(f)
with mock.patch('config.main.device_info.is_yang_config_validation_enabled',
mock.MagicMock(side_effect=is_yang_config_validation_enabled_side_effect)):
self.check_yang_verification_failure(
db, config, read_data['running_config'], read_data['golden_config'], "config_input")

def test_final_config_yang_failure(self):
def is_yang_config_validation_enabled_side_effect(filename):
return True
Expand Down
27 changes: 24 additions & 3 deletions tests/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import config.main as config
import config.validated_config_db_connector as validated_config_db_connector
from tests.config_mgmt_test import configDbJson

# Add Test, module and script path.
test_path = os.path.dirname(os.path.abspath(__file__))
Expand All @@ -35,6 +36,9 @@
sys.path.insert(0, modules_path)
sys.path.insert(0, scripts_path)
os.environ["PATH"] += os.pathsep + scripts_path
config_mgmt_py_path = os.path.join(os.path.dirname(__file__), '..', 'config', 'config_mgmt.py')
config_mgmt = load_module_from_source('config_mgmt', config_mgmt_py_path)


# Config Reload input Path
mock_db_path = os.path.join(test_path, "config_reload_input")
Expand Down Expand Up @@ -868,6 +872,11 @@ def setup_class(cls):
import config.main
importlib.reload(config.main)

def write_config_to_file(self, cfgdb, file):
with open(file, 'w') as f:
json.dump(cfgdb, f, sort_keys=True, indent=4)
return

@mock.patch('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs', mock.MagicMock(return_value=("dummy_path", None)))
def test_load_minigraph(self, get_cmd_module, setup_single_broadcom_asic):
with mock.patch("utilities_common.cli.run_command", mock.MagicMock(side_effect=mock_run_command_side_effect)) as mock_run_command:
Expand Down Expand Up @@ -991,9 +1000,15 @@ def is_file_side_effect(filename):
def read_json_file_side_effect(filename):
return {}

def config_mgmt_side_effect(configdb):
return config_mgmt.ConfigMgmt(source=CONFIG_DB_JSON_FILE)

CONFIG_DB_JSON_FILE = "startConfigDb.json"
self.write_config_to_file(configDbJson, CONFIG_DB_JSON_FILE)
with mock.patch("utilities_common.cli.run_command", mock.MagicMock(side_effect=mock_run_command_side_effect)) as mock_run_command, \
mock.patch('os.path.isfile', mock.MagicMock(side_effect=is_file_side_effect)), \
mock.patch('config.main.read_json_file', mock.MagicMock(side_effect=read_json_file_side_effect)):
mock.patch('config.main.read_json_file', mock.MagicMock(side_effect=read_json_file_side_effect)), \
mock.patch('config.main.ConfigMgmt', mock.MagicMock(side_effect=config_mgmt_side_effect)):
(config, show) = get_cmd_module
runner = CliRunner()
result = runner.invoke(config.config.commands["load_minigraph"], ["--override_config", "--golden_config_path", "golden_config.json", "-y"])
Expand All @@ -1008,9 +1023,16 @@ def is_file_side_effect(filename):
def read_json_file_side_effect(filename):
return {}

def config_mgmt_side_effect(configdb):
return config_mgmt.ConfigMgmt(source=CONFIG_DB_JSON_FILE)

CONFIG_DB_JSON_FILE = "startConfigDb.json"
self.write_config_to_file(configDbJson, CONFIG_DB_JSON_FILE)

with mock.patch("utilities_common.cli.run_command", mock.MagicMock(side_effect=mock_run_command_side_effect)) as mock_run_command, \
mock.patch('os.path.isfile', mock.MagicMock(side_effect=is_file_side_effect)), \
mock.patch('config.main.read_json_file', mock.MagicMock(side_effect=read_json_file_side_effect)):
mock.patch('config.main.read_json_file', mock.MagicMock(side_effect=read_json_file_side_effect)), \
mock.patch('config.main.ConfigMgmt', mock.MagicMock(side_effect=config_mgmt_side_effect)):
(config, show) = get_cmd_module
runner = CliRunner()
result = runner.invoke(config.config.commands["load_minigraph"], ["--override_config", "-y"])
Expand All @@ -1032,7 +1054,6 @@ def read_json_file_side_effect(filename):
},
"TACPLUS": {
"global": {
"passkey": ""
}
}
}
Expand Down

0 comments on commit 16481df

Please sign in to comment.