|
1 |
| -from sonic_py_common import device_info |
| 1 | +import os |
2 | 2 | import re
|
| 3 | +import json |
| 4 | +import jsonpointer |
| 5 | +import subprocess |
| 6 | +from sonic_py_common import device_info |
| 7 | +from .gu_common import GenericConfigUpdaterError |
| 8 | + |
| 9 | + |
| 10 | +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) |
| 11 | +GCU_TABLE_MOD_CONF_FILE = f"{SCRIPT_DIR}/gcu_field_operation_validators.conf.json" |
| 12 | +GET_HWSKU_CMD = "sonic-cfggen -d -v DEVICE_METADATA.localhost.hwsku" |
| 13 | + |
| 14 | +def get_asic_name(): |
| 15 | + asic = "unknown" |
| 16 | + |
| 17 | + if os.path.exists(GCU_TABLE_MOD_CONF_FILE): |
| 18 | + with open(GCU_TABLE_MOD_CONF_FILE, "r") as s: |
| 19 | + gcu_field_operation_conf = json.load(s) |
| 20 | + else: |
| 21 | + raise GenericConfigUpdaterError("GCU table modification validators config file not found") |
| 22 | + |
| 23 | + asic_mapping = gcu_field_operation_conf["helper_data"]["rdma_config_update_validator"] |
| 24 | + asic_type = device_info.get_sonic_version_info()['asic_type'] |
| 25 | + |
| 26 | + if asic_type == 'cisco-8000': |
| 27 | + asic = "cisco-8000" |
| 28 | + elif asic_type == 'mellanox' or asic_type == 'vs' or asic_type == 'broadcom': |
| 29 | + proc = subprocess.Popen(GET_HWSKU_CMD, shell=True, universal_newlines=True, stdout=subprocess.PIPE) |
| 30 | + output, err = proc.communicate() |
| 31 | + hwsku = output.rstrip('\n') |
| 32 | + if asic_type == 'mellanox' or asic_type == 'vs': |
| 33 | + spc1_hwskus = asic_mapping["mellanox_asics"]["spc1"] |
| 34 | + if hwsku.lower() in [spc1_hwsku.lower() for spc1_hwsku in spc1_hwskus]: |
| 35 | + asic = "spc1" |
| 36 | + return asic |
| 37 | + if asic_type == 'broadcom' or asic_type == 'vs': |
| 38 | + broadcom_asics = asic_mapping["broadcom_asics"] |
| 39 | + for asic_shorthand, hwskus in broadcom_asics.items(): |
| 40 | + if asic != "unknown": |
| 41 | + break |
| 42 | + for hwsku_cur in hwskus: |
| 43 | + if hwsku_cur.lower() in hwsku.lower(): |
| 44 | + asic = asic_shorthand |
| 45 | + break |
| 46 | + |
| 47 | + return asic |
3 | 48 |
|
4 |
| -def rdma_config_update_validator(): |
5 |
| - version_info = device_info.get_sonic_version_info() |
6 |
| - asic_type = version_info.get('asic_type') |
7 | 49 |
|
8 |
| - if (asic_type != 'mellanox' and asic_type != 'broadcom' and asic_type != 'cisco-8000'): |
| 50 | +def rdma_config_update_validator(patch_element): |
| 51 | + asic = get_asic_name() |
| 52 | + if asic == "unknown": |
9 | 53 | return False
|
| 54 | + version_info = device_info.get_sonic_version_info() |
| 55 | + build_version = version_info.get('build_version') |
| 56 | + version_substrings = build_version.split('.') |
| 57 | + branch_version = None |
| 58 | + |
| 59 | + for substring in version_substrings: |
| 60 | + if substring.isdigit() and re.match(r'^\d{8}$', substring): |
| 61 | + branch_version = substring |
| 62 | + |
| 63 | + path = patch_element["path"] |
| 64 | + table = jsonpointer.JsonPointer(path).parts[0] |
| 65 | + |
| 66 | + # Helper function to return relevant cleaned paths, consdiers case where the jsonpatch value is a dict |
| 67 | + # For paths like /PFC_WD/Ethernet112/action, remove Ethernet112 from the path so that we can clearly determine the relevant field (i.e. action, not Ethernet112) |
| 68 | + def _get_fields_in_patch(): |
| 69 | + cleaned_fields = [] |
| 70 | + |
| 71 | + field_elements = jsonpointer.JsonPointer(path).parts[1:] |
| 72 | + cleaned_field_elements = [elem for elem in field_elements if not any(char.isdigit() for char in elem)] |
| 73 | + cleaned_field = '/'.join(cleaned_field_elements).lower() |
| 74 | + |
| 75 | + |
| 76 | + if 'value' in patch_element.keys() and isinstance(patch_element['value'], dict): |
| 77 | + for key in patch_element['value']: |
| 78 | + cleaned_fields.append(cleaned_field+ '/' + key) |
| 79 | + else: |
| 80 | + cleaned_fields.append(cleaned_field) |
| 81 | + |
| 82 | + return cleaned_fields |
| 83 | + |
| 84 | + if os.path.exists(GCU_TABLE_MOD_CONF_FILE): |
| 85 | + with open(GCU_TABLE_MOD_CONF_FILE, "r") as s: |
| 86 | + gcu_field_operation_conf = json.load(s) |
| 87 | + else: |
| 88 | + raise GenericConfigUpdaterError("GCU table modification validators config file not found") |
| 89 | + |
| 90 | + tables = gcu_field_operation_conf["tables"] |
| 91 | + scenarios = tables[table]["validator_data"]["rdma_config_update_validator"] |
| 92 | + |
| 93 | + cleaned_fields = _get_fields_in_patch() |
| 94 | + for cleaned_field in cleaned_fields: |
| 95 | + scenario = None |
| 96 | + for key in scenarios.keys(): |
| 97 | + if cleaned_field in scenarios[key]["fields"]: |
| 98 | + scenario = scenarios[key] |
| 99 | + break |
| 100 | + |
| 101 | + if scenario is None: |
| 102 | + return False |
| 103 | + |
| 104 | + if scenario["platforms"][asic] == "": |
| 105 | + return False |
| 106 | + |
| 107 | + if patch_element['op'] not in scenario["operations"]: |
| 108 | + return False |
| 109 | + |
| 110 | + if branch_version is not None: |
| 111 | + if asic in scenario["platforms"]: |
| 112 | + if branch_version < scenario["platforms"][asic]: |
| 113 | + return False |
| 114 | + else: |
| 115 | + return False |
| 116 | + |
10 | 117 | return True
|
0 commit comments