Skip to content

Commit e3991d5

Browse files
Add scope to field validator. (sonic-net#3675)
What I did This is for fix issue:sonic-net#20379 How I did it For field_operation_validators, add scope if need read state_db. How to verify it admin@str2-7250-lc1-2:~$ sonic-db-cli STATE_DB -n asic0 hget "PORT_TABLE|Ethernet0" supported_fecs none,rs admin@str2-7250-lc1-2:~$ cat fec.json [ { "op": "add", "path": "/asic0/PORT/Ethernet0/fec", "value": "fc" } ] admin@str2-7250-lc1-2:~$ sudo config apply-patch fec.json Patch Applier: asic0: Patch application starting. Patch Applier: asic0: Patch: [{"op": "add", "path": "/PORT/Ethernet0/fec", "value": "fc"}] Patch Applier: asic0 getting current config db. Patch Applier: asic0: simulating the target full config after applying the patch. Patch Applier: asic0: validating all JsonPatch operations are permitted on the specified fields Failed to apply patch due to: Failed to apply patch on the following scopes: - asic0: Modification of PORT table is illegal- validating function generic_config_updater.field_operation_validators.port_config_update_validator returned False Usage: config apply-patch [OPTIONS] PATCH_FILE_PATH Try "config apply-patch -h" for help. Error: Failed to apply patch on the following scopes: - asic0: Modification of PORT table is illegal- validating function generic_config_updater.field_operation_validators.port_config_update_validator returned False
1 parent 200ef36 commit e3991d5

File tree

3 files changed

+269
-95
lines changed

3 files changed

+269
-95
lines changed

generic_config_updater/field_operation_validators.py

+18-11
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
import jsonpointer
55
import subprocess
66
from sonic_py_common import device_info
7-
from .gu_common import GenericConfigUpdaterError
7+
from .gu_common import GenericConfigUpdaterError, HOST_NAMESPACE
88
from swsscommon import swsscommon
99
from utilities_common.constants import DEFAULT_SUPPORTED_FECS_LIST
1010

11+
STATE_DB_NAME = 'STATE_DB'
12+
REDIS_TIMEOUT_MSECS = 0
1113
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
1214
GCU_TABLE_MOD_CONF_FILE = f"{SCRIPT_DIR}/gcu_field_operation_validators.conf.json"
13-
GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku"
1415

15-
def get_asic_name():
16+
17+
def get_asic_name(scope):
1618
asic = "unknown"
1719

1820
if os.path.exists(GCU_TABLE_MOD_CONF_FILE):
@@ -27,7 +29,12 @@ def get_asic_name():
2729
if asic_type == 'cisco-8000':
2830
asic = "cisco-8000"
2931
elif asic_type == 'mellanox' or asic_type == 'vs' or asic_type == 'broadcom':
30-
proc = subprocess.Popen(GET_HWSKU_CMD, shell=True, universal_newlines=True, stdout=subprocess.PIPE)
32+
get_hwsku_cmds = []
33+
if scope == HOST_NAMESPACE:
34+
get_hwsku_cmds = ["sonic-cfggen", "-d", "-v", "DEVICE_METADATA.localhost.hwsku"]
35+
else:
36+
get_hwsku_cmds = ["sonic-cfggen", "-d", "-n", scope, "-v", "DEVICE_METADATA.localhost.hwsku"]
37+
proc = subprocess.Popen(get_hwsku_cmds, shell=False, universal_newlines=True, stdout=subprocess.PIPE)
3138
output, err = proc.communicate()
3239
hwsku = output.rstrip('\n')
3340
if asic_type == 'mellanox' or asic_type == 'vs':
@@ -60,8 +67,8 @@ def get_asic_name():
6067
return asic
6168

6269

63-
def rdma_config_update_validator(patch_element):
64-
asic = get_asic_name()
70+
def rdma_config_update_validator(scope, patch_element):
71+
asic = get_asic_name(scope)
6572
if asic == "unknown":
6673
return False
6774
version_info = device_info.get_sonic_version_info()
@@ -133,17 +140,17 @@ def _get_fields_in_patch():
133140
return True
134141

135142

136-
def read_statedb_entry(table, key, field):
137-
state_db = swsscommon.DBConnector("STATE_DB", 0)
143+
def read_statedb_entry(scope, table, key, field):
144+
state_db = swsscommon.DBConnector(STATE_DB_NAME, REDIS_TIMEOUT_MSECS, True, scope)
138145
tbl = swsscommon.Table(state_db, table)
139146
return tbl.hget(key, field)[1]
140147

141148

142-
def port_config_update_validator(patch_element):
149+
def port_config_update_validator(scope, patch_element):
143150

144151
def _validate_field(field, port, value):
145152
if field == "fec":
146-
supported_fecs_str = read_statedb_entry("PORT_TABLE", port, "supported_fecs")
153+
supported_fecs_str = read_statedb_entry(scope, "PORT_TABLE", port, "supported_fecs")
147154
if supported_fecs_str:
148155
if supported_fecs_str != 'N/A':
149156
supported_fecs_list = [element.strip() for element in supported_fecs_str.split(',')]
@@ -155,7 +162,7 @@ def _validate_field(field, port, value):
155162
return False
156163
return True
157164
if field == "speed":
158-
supported_speeds_str = read_statedb_entry("PORT_TABLE", port, "supported_speeds") or ''
165+
supported_speeds_str = read_statedb_entry(scope, "PORT_TABLE", port, "supported_speeds") or ''
159166
try:
160167
supported_speeds = [int(s) for s in supported_speeds_str.split(',') if s]
161168
if supported_speeds and int(value) not in supported_speeds:

generic_config_updater/gu_common.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def _invoke_validating_function(cmd, jsonpatch_element):
191191
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))
192192
module = importlib.import_module(module_name, package=None)
193193
method_to_call = getattr(module, method_name)
194-
return method_to_call(jsonpatch_element)
194+
return method_to_call(self.scope, jsonpatch_element)
195195

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

0 commit comments

Comments
 (0)