-
Notifications
You must be signed in to change notification settings - Fork 684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GCU] Add PFC_WD RDMA validator #2619
Changes from 7 commits
fc7c841
8240d3a
e08a8fe
fdb45b3
b73ff9a
10dd1f5
77bb424
2762e49
f98fc9b
3df33e2
36761e5
633a8fe
987eaa7
735630c
0c6c24e
46c4507
c8f9249
9c15a08
80bf53f
30bd7b2
8d17240
4e29fe7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"README": [ | ||
"table_modification_validators provides, module & method name as ", | ||
" <module name>.<method name>", | ||
"NOTE: module name could have '.'", | ||
" ", | ||
"The last element separated by '.' is considered as ", | ||
"method name", | ||
"", | ||
"e.g. 'show.acl.test_acl'", | ||
"", | ||
"table_modification_validators_and for a given table defines a list of validators that all must pass for modification to the table to be allowed", | ||
"table_modification_validators_or for a given table defines a list of validators, at least one of which must pass for modification of the table to be allowed", | ||
"" | ||
], | ||
"tables": { | ||
"PFC_WD": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you reformat? mixing tabs and spaces now. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to all spaces |
||
"table_modification_validators_and": [ "generic_config_updater.validators.is_mellanox_device_validator" ], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed back to just |
||
"table_modification_validators_or": [ ] | ||
}, | ||
"BUFFER_POOL": { | ||
"table_modification_validators_and": [ "generic_config_updater.validators.is_mellanox_device_validator" ], | ||
"table_modification_validators_or": [ ] | ||
}, | ||
"WRED_PROFILE": { | ||
"table_modification_validators_and": [ "generic_config_updater.validators.is_mellanox_device_validator" ], | ||
"table_modification_validators_or": [ ] | ||
}, | ||
"QUEUE": { | ||
"table_modification_validators_and": [ "generic_config_updater.validators.is_mellanox_device_validator" ], | ||
"table_modification_validators_or": [ ] | ||
}, | ||
"BUFFER_PROFILE": { | ||
"table_modification_validators_and": [ "generic_config_updater.validators.is_mellanox_device_validator" ], | ||
"table_modification_validators_or": [ ] | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,21 @@ | ||
import json | ||
import jsonpatch | ||
import importlib | ||
from jsonpointer import JsonPointer | ||
import sonic_yang | ||
import sonic_yang_ext | ||
import subprocess | ||
import yang as ly | ||
import copy | ||
import re | ||
import os | ||
from sonic_py_common import logger | ||
from enum import Enum | ||
|
||
YANG_DIR = "/usr/local/yang-models" | ||
SYSLOG_IDENTIFIER = "GenericConfigUpdater" | ||
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) | ||
GCU_TABLE_MOD_CONF_FILE = f"{SCRIPT_DIR}/gcu_table_modification_validators.conf.json" | ||
|
||
class GenericConfigUpdaterError(Exception): | ||
pass | ||
|
@@ -155,6 +159,38 @@ def validate_field_operation(self, old_config, target_config): | |
if any(op['op'] == operation and field == op['path'] for op in patch): | ||
raise IllegalPatchOperationError("Given patch operation is invalid. Operation: {} is illegal on field: {}".format(operation, field)) | ||
|
||
def _invoke_validating_function(cmd): | ||
# cmd is in the format as <package/module name>.<method name> | ||
method_name = cmd.split(".")[-1] | ||
module_name = ".".join(cmd.split(".")[0:-1]) | ||
module = importlib.import_module(module_name, package=None) | ||
method_to_call = getattr(module, method_name) | ||
return method_to_call() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I added code to ensure the module_name is |
||
|
||
if os.path.exists(GCU_TABLE_MOD_CONF_FILE): | ||
with open(GCU_TABLE_MOD_CONF_FILE, "r") as s: | ||
gcu_table_modification_conf = json.load(s) | ||
else: | ||
raise GenericConfigUpdaterError("GCU table modification validators config file not found") | ||
|
||
for element in patch: | ||
path = element["path"] | ||
table = re.search(r'\/([^\/]+)(\/|$)', path).group(1) # This matches the table name in the path, eg. PFC_WD without the forward slashes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, I added a sample match case in the comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should not be able to reach this part of the code if there is a mismatch. When creating the jsonpatch before this part of the code is reached, the path must be a string that matches the defined regex. Else, an error will be thrown. I did add extra code to check for mismatch again if that would be more complete. |
||
validating_functions_and = set() | ||
validating_functions_or = set() | ||
tables = gcu_table_modification_conf["tables"] | ||
validating_functions_and.update(tables.get(table, {}).get("table_modification_validators_and", [])) | ||
validating_functions_or.update(tables.get(table, {}).get("table_modification_validators_or", [])) | ||
# For added flexibility in the future, we can extend the table to store a list of lists, to account for (X AND Y AND Z) OR (S AND T) | ||
|
||
for function in validating_functions_and: | ||
if not _invoke_validating_function(function): | ||
raise IllegalPatchOperationError("Modification of {} table is illegal- validating function {} returned False".format(table, function)) | ||
|
||
if validating_functions_or and not any(_invoke_validating_function(function) for function in validating_functions_or): | ||
raise IllegalPatchOperationError("Modification of {} table is illegal- all validating functions returned False".format(table)) | ||
|
||
|
||
def validate_lanes(self, config_db): | ||
if "PORT" not in config_db: | ||
return True, None | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need testcase for this file? Like tests in
service_validator_test.py
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added additional unit testing for the new RDMA-specific validator as suggested offline