Skip to content

Commit be38e33

Browse files
committed
change json structure
1 parent fc6d3eb commit be38e33

File tree

3 files changed

+149
-58
lines changed

3 files changed

+149
-58
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1+
import os
12
import re
3+
import json
24
import subprocess
35
from sonic_py_common import device_info
6+
from .gu_common import GenericConfigUpdaterError
7+
8+
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
9+
GCU_TABLE_MOD_CONF_FILE = f"{SCRIPT_DIR}/gcu_table_modification_validators.conf.json"
410

511
def get_asic_name():
612
asic = "unknown"
713
command = ["sudo", "lspci"]
814
hwsku = device_info.get_hwsku()
9-
15+
1016
proc = subprocess.Popen(command, universal_newlines=True, stdout=subprocess.PIPE)
1117
output = proc.stdout.readlines()
1218
proc.communicate()
13-
19+
1420
if proc.returncode == 0:
1521
if "Broadcom Limited Device b960" in output or "Broadcom Limited Broadcom BCM56960" in output:
1622
asic = "th"
@@ -20,29 +26,31 @@ def get_asic_name():
2026
asic = "td2"
2127
elif "Broadcom Limited Device b870" in output or "Broadcom Inc. and subsidiaries Device b870" in output:
2228
asic = "td3"
23-
29+
2430
if device_info.get_sonic_version_info()['asic_type'] == 'cisco-8000':
2531
asic = "cisco-8000"
2632
elif asic == "unknown":
2733
spc1_hwskus = [ 'ACS-MSN2700', 'ACS-MSN2740', 'ACS-MSN2100', 'ACS-MSN2410', 'ACS-MSN2010', 'Mellanox-SN2700', 'Mellanox-SN2700-D48C8' ]
2834
if hwsku.lower() in [spc1_hwsku.lower() for spc1_hwsku in spc1_hwskus]:
2935
asic = "spc1"
30-
36+
3137
return asic
3238

3339

34-
def rdma_config_update_validator(field):
40+
def rdma_config_update_validator(path, operation):
3541
version_info = device_info.get_sonic_version_info()
3642
build_version = version_info.get('build_version')
3743
asic = get_asic_name()
38-
field = field.lower()
44+
path = path.lower()
3945

46+
# For paths like /BUFFER_PROFILE/pg_lossless_50000_300m_profile/xoff, remove pg_lossless_50000_300m from the path so that we can clearly determine which fields are modifiable
47+
cleaned_path = "/".join([part for part in path.split("/") if not any(char.isdigit() for char in part)])
4048
if asic == "unknown":
4149
return False
4250

4351
version_substrings = build_version.split('.')
4452
branch_version = None
45-
53+
4654
for substring in version_substrings:
4755
if substring.isdigit() and re.match(r'^\d{8}$', substring):
4856
branch_version = substring
@@ -51,48 +59,38 @@ def rdma_config_update_validator(field):
5159
if branch_version is None:
5260
return False
5361

54-
# PFCWD enable/disable scenario
55-
if "pfc_wd" in field:
56-
if asic == 'cisco-8000':
57-
return branch_version >= "20201200"
58-
else:
59-
return branch_version >= "20181100"
60-
61-
# Shared/headroom pool size scenario
62-
elif "buffer_pool" in field:
63-
if asic in ['cisco-8000', 'td2']:
64-
return False
65-
if asic == 'spc1':
66-
return branch_version >= "20191100"
67-
if asic in ['th', 'th2', 'td3']:
68-
return branch_version >= "20221100"
69-
70-
# Dynamic threshold tuning scenario
71-
elif "buffer_profile" in field and "dynamic_th" in field:
72-
if asic == 'cisco-8000':
73-
return False
74-
if asic in ['spc1', 'td2', 'th', 'th2']:
75-
return branch_version >= "20181100"
76-
elif asic == 'td3':
77-
return branch_version >= "20201200"
62+
if os.path.exists(GCU_TABLE_MOD_CONF_FILE):
63+
with open(GCU_TABLE_MOD_CONF_FILE, "r") as s:
64+
gcu_field_operation_conf = json.load(s)
65+
else:
66+
raise GenericConfigUpdaterError("GCU table modification validators config file not found")
67+
68+
match = re.search(r'\/([^\/]+)(\/|$)', cleaned_path) # This matches the table name in the path, eg if path if /PFC_WD/GLOBAL, the match would be PFC_WD
69+
if match is not None:
70+
table = match.group(1)
71+
index = cleaned_path.index(table) + len(table)
72+
field = cleaned_path[index:].lstrip('/')
73+
else:
74+
raise GenericConfigUpdaterError("Invalid jsonpatch path: {}".format(path))
75+
76+
tables = gcu_field_operation_conf["tables"]
77+
scenarios = tables[table]["validator_data"]["rdma_config_update_validator"]
78+
scenario = None
79+
for key in scenarios.keys():
80+
if field in scenarios[key]["fields"]:
81+
scenario = scenarios[key]
82+
break
83+
84+
if scenario is None:
85+
return False
7886

79-
# ECN tuning scenario
80-
elif "wred_profile" in field:
81-
if asic == 'cisco-8000':
82-
return False
83-
elif asic in ['spc1', 'td2', 'th', 'th2']:
84-
return branch_version >= "20181100"
85-
elif asic == 'td3':
86-
return branch_version >= "20201200"
87+
if operation not in scenario["operations"]:
88+
return False
8789

88-
# PG headroom modification scenario
89-
elif "buffer_profile" in field and "xoff" in field:
90-
if asic in ['cisco-8000', 'td2']:
90+
if platform in scenario["platforms"]:
91+
if version < scenario["platforms"][platform]:
9192
return False
92-
elif asic == 'spc1':
93-
return branch_version >= "20191100"
94-
elif asic in ['th', 'th2', 'td3']:
95-
return branch_version >= "20221100"
96-
97-
return False
93+
else:
94+
return False
9895

96+
return True

generic_config_updater/gcu_field_operation_validators.conf.json

+102-9
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,114 @@
99
"",
1010
"e.g. 'show.acl.test_acl'",
1111
"",
12-
"field_operation_validators for a given table defines a list of validators that all must pass for modification to the specified field and table to be allowed",
12+
"table_operation_validators for a given table defines a list of validators that all must pass for modification to the table to be allowed",
13+
"",
14+
"validator_data provides data relevant to each validator",
1315
""
1416
],
1517
"tables": {
16-
"PFC_WD": {
17-
"field_operation_validators": [ "generic_config_updater.field_operation_validators.rdma_config_update_validator" ]
18+
"pfc_wd": {
19+
"field_operation_validators": [ "generic_config_updater.field_operation_validators.rdma_config_update_validator" ],
20+
"validator_data": {
21+
"rdma_config_update_validator": {
22+
"PFCWD enable/disable": {
23+
"fields": [
24+
"restoration_time",
25+
"detection_time",
26+
"action"
27+
],
28+
"operations": ["remove", "add", "replace"],
29+
"platforms": {
30+
"spc1": "20181100",
31+
"td2": "20181100",
32+
"th": "20181100",
33+
"th2": "20181100",
34+
"td3": "20181100",
35+
"cisco-8000": "20201200"
36+
}
37+
}
38+
}
39+
}
1840
},
19-
"BUFFER_POOL": {
20-
"table_modification_validators": [ "generic_config_updater.field_operation_validators.rdma_config_update_validator" ]
41+
"buffer_pool": {
42+
"field_operation_validators": [ "generic_config_updater.field_operation_validators.rdma_config_update_validator" ],
43+
"validator_data": {
44+
"rdma_config_update_validator": {
45+
"Shared/headroom pool size changes": {
46+
"fields": [
47+
"ingress_lossless_pool/xoff",
48+
"ingress_lossless_pool/size",
49+
"egress_lossy_pool/size"
50+
],
51+
"operations": ["replace"],
52+
"platforms": {
53+
"spc1": "20191100",
54+
"td2": "",
55+
"th": "20221100",
56+
"th2": "20221100",
57+
"td3": "20221100",
58+
"cisco-8000": ""
59+
}
60+
}
61+
}
62+
}
2163
},
22-
"BUFFER_PROFILE": {
23-
"table_modification_validators": [ "generic_config_updater.field_operation_validators.rdma_config_update_validator" ]
64+
"buffer_profile": {
65+
"field_operation_validators": [ "generic_config_updater.field_operation_validators.rdma_config_update_validator" ],
66+
"validator_data": {
67+
"rdma_config_update_validator": {
68+
"Dynamic threshold tuning": {
69+
"fields": [
70+
"dynamic_th"
71+
],
72+
"operations": ["replace"],
73+
"platforms": {
74+
"spc1": "20181100",
75+
"td2": "20181100",
76+
"th": "20181100",
77+
"th2": "20181100",
78+
"td3": "20201200",
79+
"cisco-8000": ""
80+
}
81+
},
82+
"PG headroom modification": {
83+
"fields": [
84+
"xoff"
85+
],
86+
"operations": ["replace"],
87+
"platforms": {
88+
"spc1": "20191100",
89+
"td2": "",
90+
"th": "20221100",
91+
"th2": "20221100",
92+
"td3": "20221100",
93+
"cisco-8000": ""
94+
}
95+
}
96+
}
97+
}
2498
},
25-
"WRED_PROFILE": {
26-
"table_modification_validators": [ "generic_config_updater.field_operation_validators.rdma_config_update_validator" ]
99+
"wred_profile": {
100+
"field_operation_validators": [ "generic_config_updater.field_operation_validators.rdma_config_update_validator" ],
101+
"validator_data": {
102+
"rdma_config_update_validator": {
103+
"ECN tuning": {
104+
"fields": [
105+
"azure_lossless/green_min_threshold",
106+
"azure_lossless/green_max_threshold"
107+
],
108+
"operations": ["replace"],
109+
"platforms": {
110+
"spc1": "20181100",
111+
"td2": "20181100",
112+
"th": "20181100",
113+
"th2": "20181100",
114+
"td3": "20201200",
115+
"cisco-8000": ""
116+
}
117+
}
118+
}
119+
}
27120
}
28121
}
29122
}

generic_config_updater/gu_common.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def _invoke_validating_function(cmd):
174174
raise GenericConfigUpdaterError("Attempting to call invalid method {} in module {}. Module must be generic_config_updater.field_operation_validators, and method must be a defined validator".format(method_name, module_name))
175175
module = importlib.import_module(module_name, package=None)
176176
method_to_call = getattr(module, method_name)
177-
return method_to_call()
177+
return method_to_call(path, operation)
178178

179179
if os.path.exists(GCU_FIELD_OP_CONF_FILE):
180180
with open(GCU_FIELD_OP_CONF_FILE, "r") as s:

0 commit comments

Comments
 (0)