Skip to content

Commit 0b41a56

Browse files
authored
[config] Add YANG alerting for override (#3188)
#### What I did Add alerting for YANG validation when load_minigraph during override. This is to alert early if golden config is invalid which will breaks GCU feature. #### How I did it Add alerting when `is_yang_config_validation_enabled` is not set during load_minigraph with override #### How to verify it Unit test
1 parent 24683b0 commit 0b41a56

6 files changed

Lines changed: 65 additions & 25 deletions

File tree

config/main.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,6 +1979,18 @@ def override_config_table(db, input_config_db, dry_run):
19791979
validate_config_by_cm(cm, ns_config_input, "config_input")
19801980
# Validate updated whole config
19811981
validate_config_by_cm(cm, updated_config, "updated_config")
1982+
else:
1983+
cm = None
1984+
try:
1985+
# YANG validate of config minigraph generated
1986+
cm = ConfigMgmt(configdb=config_db)
1987+
cm.validateConfigData()
1988+
except Exception as ex:
1989+
log.log_warning("Failed to validate running config. Alerting: {}".format(ex))
1990+
1991+
# YANG validate config of minigraph generated overriden by golden config
1992+
if cm:
1993+
validate_config_by_cm_alerting(cm, updated_config, "updated_config")
19821994

19831995
if dry_run:
19841996
print(json.dumps(updated_config, sort_keys=True,
@@ -1997,6 +2009,15 @@ def validate_config_by_cm(cm, config_json, jname):
19972009
sys.exit(1)
19982010

19992011

2012+
def validate_config_by_cm_alerting(cm, config_json, jname):
2013+
tmp_config_json = copy.deepcopy(config_json)
2014+
try:
2015+
cm.loadData(tmp_config_json)
2016+
cm.validateConfigData()
2017+
except Exception as ex:
2018+
log.log_warning("Failed to validate {}. Alerting: {}".format(jname, ex))
2019+
2020+
20002021
def override_config_db(config_db, config_input):
20012022
# Deserialized golden config to DB recognized format
20022023
sonic_cfggen.FormatConverter.to_deserialized(config_input)

tests/config_override_input/multi_asic_dm_rm.json

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"localhost": {
3+
"FEATURE": {}
4+
},
5+
"asic0": {
6+
"FEATURE": {}
7+
},
8+
"asic1": {
9+
"FEATURE": {}
10+
}
11+
}

tests/config_override_input/multi_asic_macsec_ov.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,30 @@
22
"localhost": {
33
"MACSEC_PROFILE": {
44
"profile": {
5-
"key": "value"
5+
"primary_cak": "1159485744465e5a537272050a1011073557475152020c0e040c57223a357d7d71",
6+
"primary_ckn": "6162636465666768696A6B6C6D6E6F70",
7+
"fallback_cak": "000000000000000000000000000000000000000000000000000000000000000000",
8+
"fallback_ckn": "11111111111111111111111111111111"
69
}
710
}
811
},
912
"asic0": {
1013
"MACSEC_PROFILE": {
1114
"profile": {
12-
"key": "value"
15+
"primary_cak": "1159485744465e5a537272050a1011073557475152020c0e040c57223a357d7d71",
16+
"primary_ckn": "6162636465666768696A6B6C6D6E6F70",
17+
"fallback_cak": "000000000000000000000000000000000000000000000000000000000000000000",
18+
"fallback_ckn": "11111111111111111111111111111111"
1319
}
1420
}
1521
},
1622
"asic1": {
1723
"MACSEC_PROFILE": {
1824
"profile": {
19-
"key": "value"
25+
"primary_cak": "1159485744465e5a537272050a1011073557475152020c0e040c57223a357d7d71",
26+
"primary_ckn": "6162636465666768696A6B6C6D6E6F70",
27+
"fallback_cak": "000000000000000000000000000000000000000000000000000000000000000000",
28+
"fallback_ckn": "11111111111111111111111111111111"
2029
}
2130
}
2231
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"localhost": {
3-
"DEVICE_METADATA": {}
3+
"FEATURE": {}
44
},
55
"asic0": {
6-
"DEVICE_METADATA": {}
6+
"FEATURE": {}
77
}
88
}

tests/config_override_test.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
GOLDEN_INPUT_YANG_FAILURE = os.path.join(DATA_DIR, "golden_input_yang_failure.json")
2424
FINAL_CONFIG_YANG_FAILURE = os.path.join(DATA_DIR, "final_config_yang_failure.json")
2525
MULTI_ASIC_MACSEC_OV = os.path.join(DATA_DIR, "multi_asic_macsec_ov.json")
26-
MULTI_ASIC_DEVICE_METADATA_RM = os.path.join(DATA_DIR, "multi_asic_dm_rm.json")
26+
MULTI_ASIC_FEATURE_RM = os.path.join(DATA_DIR, "multi_asic_feature_rm.json")
2727
MULTI_ASIC_DEVICE_METADATA_GEN_SYSINFO = os.path.join(DATA_DIR, "multi_asic_dm_gen_sysinfo.json")
2828
MULTI_ASIC_MISSING_LOCALHOST_OV = os.path.join(DATA_DIR, "multi_asic_missing_localhost.json")
2929
MULTI_ASIC_MISSING_ASIC_OV = os.path.join(DATA_DIR, "multi_asic_missing_asic.json")
@@ -105,7 +105,9 @@ def read_json_file_side_effect(filename):
105105
['golden_config_db.json', '--dry-run'])
106106

107107
assert result.exit_code == 0
108-
assert json.loads(result.output) == current_config
108+
start_pos = result.output.find('{')
109+
json_text = result.output[start_pos:]
110+
assert json.loads(json_text) == current_config
109111

110112
def test_golden_config_db_empty(self):
111113
db = Db()
@@ -308,7 +310,15 @@ def read_json_file_side_effect(filename):
308310

309311
# The profile_content was copied from MULTI_ASIC_MACSEC_OV, where all
310312
# ns sharing the same content: {"profile": {"key": "value"}}
311-
profile_content = {"profile": {"key": "value"}}
313+
profile_content = {
314+
"profile": {
315+
"primary_cak": "1159485744465e5a537272050a1011073557475152020c0e040c57223a357d7d71",
316+
"primary_ckn": "6162636465666768696A6B6C6D6E6F70",
317+
"fallback_cak": "000000000000000000000000000000000000000000000000000000000000000000",
318+
"fallback_ckn": "11111111111111111111111111111111"
319+
320+
}
321+
}
312322

313323
with mock.patch('config.main.read_json_file',
314324
mock.MagicMock(side_effect=read_json_file_side_effect)):
@@ -320,16 +330,16 @@ def read_json_file_side_effect(filename):
320330
for ns, config_db in cfgdb_clients.items():
321331
assert config_db.get_config()['MACSEC_PROFILE'] == profile_content
322332

323-
def test_device_metadata_table_rm(self):
333+
def test_feature_table_rm(self):
324334
def read_json_file_side_effect(filename):
325-
with open(MULTI_ASIC_DEVICE_METADATA_RM, "r") as f:
326-
device_metadata = json.load(f)
327-
return device_metadata
335+
with open(MULTI_ASIC_FEATURE_RM, "r") as f:
336+
feature = json.load(f)
337+
return feature
328338
db = Db()
329339
cfgdb_clients = db.cfgdb_clients
330340

331341
for ns, config_db in cfgdb_clients.items():
332-
assert 'DEVICE_METADATA' in config_db.get_config()
342+
assert 'FEATURE' in config_db.get_config()
333343

334344
with mock.patch('config.main.read_json_file',
335345
mock.MagicMock(side_effect=read_json_file_side_effect)):
@@ -339,7 +349,7 @@ def read_json_file_side_effect(filename):
339349
assert result.exit_code == 0
340350

341351
for ns, config_db in cfgdb_clients.items():
342-
assert 'DEVICE_METADATA' not in config_db.get_config()
352+
assert 'FEATURE' not in config_db.get_config()
343353

344354
def test_device_metadata_keep_sysinfo(self):
345355
def read_json_file_side_effect(filename):

0 commit comments

Comments
 (0)