Skip to content

Commit 3d8e9c6

Browse files
authored
[GCU] Prohibit removal of PFC_WD POLL_INTERVAL field (#2545)
1 parent 163e766 commit 3d8e9c6

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

generic_config_updater/generic_updater.py

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def apply(self, patch):
4747
# Generate target config
4848
self.logger.log_notice("Simulating the target full config after applying the patch.")
4949
target_config = self.patch_wrapper.simulate_patch(patch, old_config)
50+
51+
# Validate all JsonPatch operations on specified fields
52+
self.logger.log_notice("Validating all JsonPatch operations are permitted on the specified fields")
53+
self.config_wrapper.validate_field_operation(old_config, target_config)
5054

5155
# Validate target config does not have empty tables since they do not show up in ConfigDb
5256
self.logger.log_notice("Validating target config does not have empty tables, " \

generic_config_updater/gu_common.py

+19
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
class GenericConfigUpdaterError(Exception):
1717
pass
1818

19+
class IllegalPatchOperationError(ValueError):
20+
pass
21+
1922
class EmptyTableError(ValueError):
2023
pass
2124

@@ -136,6 +139,22 @@ def validate_config_db_config(self, config_db_as_json):
136139

137140
return True, None
138141

142+
def validate_field_operation(self, old_config, target_config):
143+
"""
144+
Some fields in ConfigDB are restricted and may not allow third-party addition, replacement, or removal.
145+
Because YANG only validates state and not transitions, this method helps to JsonPatch operations/transitions for the specified fields.
146+
"""
147+
patch = jsonpatch.JsonPatch.from_diff(old_config, target_config)
148+
149+
# illegal_operations_to_fields_map['remove'] yields a list of fields for which `remove` is an illegal operation
150+
illegal_operations_to_fields_map = {'add':[],
151+
'replace': [],
152+
'remove': ['/PFC_WD/GLOBAL/POLL_INTERVAL', '/PFC_WD/GLOBAL']}
153+
for operation, field_list in illegal_operations_to_fields_map.items():
154+
for field in field_list:
155+
if any(op['op'] == operation and field == op['path'] for op in patch):
156+
raise IllegalPatchOperationError("Given patch operation is invalid. Operation: {} is illegal on field: {}".format(operation, field))
157+
139158
def validate_lanes(self, config_db):
140159
if "PORT" not in config_db:
141160
return True, None

tests/generic_config_updater/gu_common_test.py

+12
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ def setUp(self):
5757
self.config_wrapper_mock = gu_common.ConfigWrapper()
5858
self.config_wrapper_mock.get_config_db_as_json=MagicMock(return_value=Files.CONFIG_DB_AS_JSON)
5959

60+
def test_validate_field_operation_legal(self):
61+
old_config = {"PFC_WD": {"GLOBAL": {"POLL_INTERVAL": "60"}}}
62+
target_config = {"PFC_WD": {"GLOBAL": {"POLL_INTERVAL": "40"}}}
63+
config_wrapper = gu_common.ConfigWrapper()
64+
config_wrapper.validate_field_operation(old_config, target_config)
65+
66+
def test_validate_field_operation_illegal(self):
67+
old_config = {"PFC_WD": {"GLOBAL": {"POLL_INTERVAL": 60}}}
68+
target_config = {"PFC_WD": {"GLOBAL": {}}}
69+
config_wrapper = gu_common.ConfigWrapper()
70+
self.assertRaises(gu_common.IllegalPatchOperationError, config_wrapper.validate_field_operation, old_config, target_config)
71+
6072
def test_ctor__default_values_set(self):
6173
config_wrapper = gu_common.ConfigWrapper()
6274

0 commit comments

Comments
 (0)