Lei YU | 43082e7 | 2020-03-09 10:32:48 +0800 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 2 | |
| 3 | import argparse |
| 4 | import json |
Bob King | b7552f0 | 2020-10-15 14:34:17 +0800 | [diff] [blame] | 5 | import os |
| 6 | import sys |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 7 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 8 | import jsonschema |
| 9 | |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 10 | r""" |
| 11 | Validates the phosphor-regulators configuration file. Checks it against a JSON |
| 12 | schema as well as doing some extra checks that can't be encoded in the schema. |
| 13 | """ |
| 14 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 15 | |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 16 | def handle_validation_error(): |
| 17 | sys.exit("Validation failed.") |
| 18 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 19 | |
| 20 | def get_values(json_element, key, result=None): |
Bob King | 23dd60b | 2020-02-26 10:23:21 +0800 | [diff] [blame] | 21 | r""" |
| 22 | Finds all occurrences of a key within the specified JSON element and its |
| 23 | children. Returns the associated values. |
| 24 | To search the entire configuration file, pass the root JSON element |
| 25 | json_element: JSON element within the config file. |
| 26 | key: key name. |
| 27 | result: list of values found with the specified key. |
| 28 | """ |
| 29 | |
| 30 | if result is None: |
| 31 | result = [] |
| 32 | if type(json_element) is dict: |
| 33 | for json_key in json_element: |
| 34 | if json_key == key: |
| 35 | result.append(json_element[json_key]) |
| 36 | elif type(json_element[json_key]) in (list, dict): |
| 37 | get_values(json_element[json_key], key, result) |
| 38 | elif type(json_element) is list: |
| 39 | for item in json_element: |
| 40 | if type(item) in (list, dict): |
| 41 | get_values(item, key, result) |
| 42 | return result |
| 43 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 44 | |
Bob King | 23dd60b | 2020-02-26 10:23:21 +0800 | [diff] [blame] | 45 | def get_rule_ids(config_json): |
| 46 | r""" |
| 47 | Get all rule IDs in the configuration file. |
| 48 | config_json: Configuration file JSON |
| 49 | """ |
| 50 | rule_ids = [] |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 51 | for rule in config_json.get("rules", {}): |
| 52 | rule_ids.append(rule["id"]) |
Bob King | 23dd60b | 2020-02-26 10:23:21 +0800 | [diff] [blame] | 53 | return rule_ids |
| 54 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 55 | |
Bob King | e959754 | 2020-02-26 10:47:40 +0800 | [diff] [blame] | 56 | def get_device_ids(config_json): |
| 57 | r""" |
| 58 | Get all device IDs in the configuration file. |
| 59 | config_json: Configuration file JSON |
| 60 | """ |
| 61 | device_ids = [] |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 62 | for chassis in config_json.get("chassis", {}): |
| 63 | for device in chassis.get("devices", {}): |
| 64 | device_ids.append(device["id"]) |
Bob King | e959754 | 2020-02-26 10:47:40 +0800 | [diff] [blame] | 65 | return device_ids |
| 66 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 67 | |
Bob King | a533d70 | 2020-02-26 10:51:24 +0800 | [diff] [blame] | 68 | def check_number_of_elements_in_masks(config_json): |
| 69 | r""" |
| 70 | Check if the number of bit masks in the 'masks' property matches the number |
| 71 | of byte values in the 'values' property. |
| 72 | config_json: Configuration file JSON |
| 73 | """ |
| 74 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 75 | i2c_write_bytes = get_values(config_json, "i2c_write_bytes") |
| 76 | i2c_compare_bytes = get_values(config_json, "i2c_compare_bytes") |
Bob King | a533d70 | 2020-02-26 10:51:24 +0800 | [diff] [blame] | 77 | |
| 78 | for object in i2c_write_bytes: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 79 | if "masks" in object: |
| 80 | if len(object.get("masks", [])) != len(object.get("values", [])): |
| 81 | sys.stderr.write( |
| 82 | "Error: Invalid i2c_write_bytes action.\n" |
| 83 | + "The masks array must have the same size as the values" |
| 84 | + " array. masks: " |
| 85 | + str(object.get("masks", [])) |
| 86 | + ", values: " |
| 87 | + str(object.get("values", [])) |
| 88 | + ".\n" |
| 89 | ) |
Bob King | a533d70 | 2020-02-26 10:51:24 +0800 | [diff] [blame] | 90 | handle_validation_error() |
| 91 | |
| 92 | for object in i2c_compare_bytes: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 93 | if "masks" in object: |
| 94 | if len(object.get("masks", [])) != len(object.get("values", [])): |
| 95 | sys.stderr.write( |
| 96 | "Error: Invalid i2c_compare_bytes action.\n" |
| 97 | + "The masks array must have the same size as the values " |
| 98 | + "array. masks: " |
| 99 | + str(object.get("masks", [])) |
| 100 | + ", values: " |
| 101 | + str(object.get("values", [])) |
| 102 | + ".\n" |
| 103 | ) |
Bob King | a533d70 | 2020-02-26 10:51:24 +0800 | [diff] [blame] | 104 | handle_validation_error() |
| 105 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 106 | |
Bob King | 9146df2 | 2020-02-26 10:49:33 +0800 | [diff] [blame] | 107 | def check_rule_id_exists(config_json): |
| 108 | r""" |
| 109 | Check if a rule_id property specifies a rule ID that does not exist. |
| 110 | config_json: Configuration file JSON |
| 111 | """ |
| 112 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 113 | rule_ids = get_values(config_json, "rule_id") |
Bob King | 9146df2 | 2020-02-26 10:49:33 +0800 | [diff] [blame] | 114 | valid_rule_ids = get_rule_ids(config_json) |
| 115 | for rule_id in rule_ids: |
| 116 | if rule_id not in valid_rule_ids: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 117 | sys.stderr.write( |
| 118 | "Error: Rule ID does not exist.\n" |
| 119 | + "Found rule_id value that specifies invalid rule ID " |
| 120 | + rule_id |
| 121 | + "\n" |
| 122 | ) |
Bob King | 9146df2 | 2020-02-26 10:49:33 +0800 | [diff] [blame] | 123 | handle_validation_error() |
| 124 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 125 | |
Shawn McCarney | 5d4a9c7 | 2021-08-19 18:45:59 -0500 | [diff] [blame] | 126 | def check_device_id_exists(config_json): |
| 127 | r""" |
| 128 | Check if a device_id property specifies a device ID that does not exist. |
| 129 | config_json: Configuration file JSON |
| 130 | """ |
| 131 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 132 | device_ids = get_values(config_json, "device_id") |
Shawn McCarney | 5d4a9c7 | 2021-08-19 18:45:59 -0500 | [diff] [blame] | 133 | valid_device_ids = get_device_ids(config_json) |
| 134 | for device_id in device_ids: |
| 135 | if device_id not in valid_device_ids: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 136 | sys.stderr.write( |
| 137 | "Error: Device ID does not exist.\n" |
| 138 | + "Found device_id value that specifies invalid device ID " |
| 139 | + device_id |
| 140 | + "\n" |
| 141 | ) |
Shawn McCarney | 5d4a9c7 | 2021-08-19 18:45:59 -0500 | [diff] [blame] | 142 | handle_validation_error() |
| 143 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 144 | |
Bob King | e959754 | 2020-02-26 10:47:40 +0800 | [diff] [blame] | 145 | def check_set_device_value_exists(config_json): |
| 146 | r""" |
| 147 | Check if a set_device action specifies a device ID that does not exist. |
| 148 | config_json: Configuration file JSON |
| 149 | """ |
| 150 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 151 | device_ids = get_values(config_json, "set_device") |
Bob King | e959754 | 2020-02-26 10:47:40 +0800 | [diff] [blame] | 152 | valid_device_ids = get_device_ids(config_json) |
| 153 | for device_id in device_ids: |
| 154 | if device_id not in valid_device_ids: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 155 | sys.stderr.write( |
| 156 | "Error: Device ID does not exist.\n" |
| 157 | + "Found set_device action that specifies invalid device ID " |
| 158 | + device_id |
| 159 | + "\n" |
| 160 | ) |
Bob King | e959754 | 2020-02-26 10:47:40 +0800 | [diff] [blame] | 161 | handle_validation_error() |
| 162 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 163 | |
Bob King | 23dd60b | 2020-02-26 10:23:21 +0800 | [diff] [blame] | 164 | def check_run_rule_value_exists(config_json): |
| 165 | r""" |
| 166 | Check if any run_rule actions specify a rule ID that does not exist. |
| 167 | config_json: Configuration file JSON |
| 168 | """ |
| 169 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 170 | rule_ids = get_values(config_json, "run_rule") |
Bob King | 23dd60b | 2020-02-26 10:23:21 +0800 | [diff] [blame] | 171 | valid_rule_ids = get_rule_ids(config_json) |
| 172 | for rule_id in rule_ids: |
| 173 | if rule_id not in valid_rule_ids: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 174 | sys.stderr.write( |
| 175 | "Error: Rule ID does not exist.\n" |
| 176 | + "Found run_rule action that specifies invalid rule ID " |
| 177 | + rule_id |
| 178 | + "\n" |
| 179 | ) |
Bob King | 23dd60b | 2020-02-26 10:23:21 +0800 | [diff] [blame] | 180 | handle_validation_error() |
| 181 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 182 | |
Bob King | d114cd9 | 2020-02-10 13:56:02 +0800 | [diff] [blame] | 183 | def check_infinite_loops_in_rule(config_json, rule_json, call_stack=[]): |
| 184 | r""" |
| 185 | Check if a 'run_rule' action in the specified rule causes an |
| 186 | infinite loop. |
| 187 | config_json: Configuration file JSON. |
| 188 | rule_json: A rule in the JSON config file. |
| 189 | call_stack: Current call stack of rules. |
| 190 | """ |
| 191 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 192 | call_stack.append(rule_json["id"]) |
| 193 | for action in rule_json.get("actions", {}): |
| 194 | if "run_rule" in action: |
| 195 | run_rule_id = action["run_rule"] |
Bob King | d114cd9 | 2020-02-10 13:56:02 +0800 | [diff] [blame] | 196 | if run_rule_id in call_stack: |
| 197 | call_stack.append(run_rule_id) |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 198 | sys.stderr.write( |
| 199 | "Infinite loop caused by run_rule actions.\n" |
| 200 | + str(call_stack) |
| 201 | + "\n" |
| 202 | ) |
Bob King | d114cd9 | 2020-02-10 13:56:02 +0800 | [diff] [blame] | 203 | handle_validation_error() |
| 204 | else: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 205 | for rule in config_json.get("rules", {}): |
| 206 | if rule["id"] == run_rule_id: |
| 207 | check_infinite_loops_in_rule( |
| 208 | config_json, rule, call_stack |
| 209 | ) |
Bob King | d114cd9 | 2020-02-10 13:56:02 +0800 | [diff] [blame] | 210 | call_stack.pop() |
| 211 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 212 | |
Bob King | d114cd9 | 2020-02-10 13:56:02 +0800 | [diff] [blame] | 213 | def check_infinite_loops(config_json): |
| 214 | r""" |
| 215 | Check if rule in config file is called recursively, causing an |
| 216 | infinite loop. |
| 217 | config_json: Configuration file JSON |
| 218 | """ |
| 219 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 220 | for rule in config_json.get("rules", {}): |
Bob King | d114cd9 | 2020-02-10 13:56:02 +0800 | [diff] [blame] | 221 | check_infinite_loops_in_rule(config_json, rule) |
| 222 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 223 | |
Bob King | 5b27a95 | 2020-01-20 18:04:15 +0800 | [diff] [blame] | 224 | def check_duplicate_object_id(config_json): |
| 225 | r""" |
| 226 | Check that there aren't any JSON objects with the same 'id' property value. |
| 227 | config_json: Configuration file JSON |
| 228 | """ |
| 229 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 230 | json_ids = get_values(config_json, "id") |
Bob King | 5b27a95 | 2020-01-20 18:04:15 +0800 | [diff] [blame] | 231 | unique_ids = set() |
| 232 | for id in json_ids: |
| 233 | if id in unique_ids: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 234 | sys.stderr.write( |
| 235 | "Error: Duplicate ID.\n" |
| 236 | + "Found multiple objects with the ID " |
| 237 | + id |
| 238 | + "\n" |
| 239 | ) |
| 240 | handle_validation_error() |
Bob King | 5b27a95 | 2020-01-20 18:04:15 +0800 | [diff] [blame] | 241 | else: |
| 242 | unique_ids.add(id) |
| 243 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 244 | |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 245 | def check_duplicate_rule_id(config_json): |
| 246 | r""" |
| 247 | Check that there aren't any "rule" elements with the same 'id' field. |
| 248 | config_json: Configuration file JSON |
| 249 | """ |
| 250 | rule_ids = [] |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 251 | for rule in config_json.get("rules", {}): |
| 252 | rule_id = rule["id"] |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 253 | if rule_id in rule_ids: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 254 | sys.stderr.write( |
| 255 | "Error: Duplicate rule ID.\n" |
| 256 | + "Found multiple rules with the ID " |
| 257 | + rule_id |
| 258 | + "\n" |
| 259 | ) |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 260 | handle_validation_error() |
| 261 | else: |
| 262 | rule_ids.append(rule_id) |
| 263 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 264 | |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 265 | def check_duplicate_chassis_number(config_json): |
| 266 | r""" |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 267 | Check that there aren't any "chassis" elements with the same 'number' |
| 268 | field. |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 269 | config_json: Configuration file JSON |
| 270 | """ |
| 271 | numbers = [] |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 272 | for chassis in config_json.get("chassis", {}): |
| 273 | number = chassis["number"] |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 274 | if number in numbers: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 275 | sys.stderr.write( |
| 276 | "Error: Duplicate chassis number.\n" |
| 277 | + "Found multiple chassis with the number " |
| 278 | + str(number) |
| 279 | + "\n" |
| 280 | ) |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 281 | handle_validation_error() |
| 282 | else: |
| 283 | numbers.append(number) |
| 284 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 285 | |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 286 | def check_duplicate_device_id(config_json): |
| 287 | r""" |
| 288 | Check that there aren't any "devices" with the same 'id' field. |
| 289 | config_json: Configuration file JSON |
| 290 | """ |
| 291 | device_ids = [] |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 292 | for chassis in config_json.get("chassis", {}): |
| 293 | for device in chassis.get("devices", {}): |
| 294 | device_id = device["id"] |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 295 | if device_id in device_ids: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 296 | sys.stderr.write( |
| 297 | "Error: Duplicate device ID.\n" |
| 298 | + "Found multiple devices with the ID " |
| 299 | + device_id |
| 300 | + "\n" |
| 301 | ) |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 302 | handle_validation_error() |
| 303 | else: |
| 304 | device_ids.append(device_id) |
| 305 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 306 | |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 307 | def check_duplicate_rail_id(config_json): |
| 308 | r""" |
| 309 | Check that there aren't any "rails" with the same 'id' field. |
| 310 | config_json: Configuration file JSON |
| 311 | """ |
| 312 | rail_ids = [] |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 313 | for chassis in config_json.get("chassis", {}): |
| 314 | for device in chassis.get("devices", {}): |
| 315 | for rail in device.get("rails", {}): |
| 316 | rail_id = rail["id"] |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 317 | if rail_id in rail_ids: |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 318 | sys.stderr.write( |
| 319 | "Error: Duplicate rail ID.\n" |
| 320 | + "Found multiple rails with the ID " |
| 321 | + rail_id |
| 322 | + "\n" |
| 323 | ) |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 324 | handle_validation_error() |
| 325 | else: |
| 326 | rail_ids.append(rail_id) |
| 327 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 328 | |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 329 | def check_for_duplicates(config_json): |
| 330 | r""" |
| 331 | Check for duplicate ID. |
| 332 | """ |
| 333 | check_duplicate_rule_id(config_json) |
| 334 | |
| 335 | check_duplicate_chassis_number(config_json) |
| 336 | |
| 337 | check_duplicate_device_id(config_json) |
| 338 | |
| 339 | check_duplicate_rail_id(config_json) |
| 340 | |
Bob King | 5b27a95 | 2020-01-20 18:04:15 +0800 | [diff] [blame] | 341 | check_duplicate_object_id(config_json) |
| 342 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 343 | |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 344 | def validate_schema(config, schema): |
| 345 | r""" |
| 346 | Validates the specified config file using the specified |
| 347 | schema file. |
| 348 | |
| 349 | config: Path of the file containing the config JSON |
| 350 | schema: Path of the file containing the schema JSON |
| 351 | """ |
| 352 | |
| 353 | with open(config) as config_handle: |
| 354 | config_json = json.load(config_handle) |
| 355 | |
| 356 | with open(schema) as schema_handle: |
| 357 | schema_json = json.load(schema_handle) |
| 358 | |
| 359 | try: |
| 360 | jsonschema.validate(config_json, schema_json) |
| 361 | except jsonschema.ValidationError as e: |
| 362 | print(e) |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 363 | handle_validation_error() |
| 364 | |
| 365 | return config_json |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 366 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 367 | |
Bob King | b7552f0 | 2020-10-15 14:34:17 +0800 | [diff] [blame] | 368 | def validate_JSON_format(file): |
| 369 | with open(file) as json_data: |
| 370 | try: |
| 371 | return json.load(json_data) |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 372 | except ValueError: |
Bob King | b7552f0 | 2020-10-15 14:34:17 +0800 | [diff] [blame] | 373 | return False |
| 374 | return True |
| 375 | |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 376 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 377 | if __name__ == "__main__": |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 378 | parser = argparse.ArgumentParser( |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 379 | description="phosphor-regulators configuration file validator" |
| 380 | ) |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 381 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 382 | parser.add_argument( |
| 383 | "-s", |
| 384 | "--schema-file", |
| 385 | dest="schema_file", |
| 386 | help="The phosphor-regulators schema file", |
| 387 | ) |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 388 | |
Patrick Williams | a93243d | 2022-12-05 09:20:34 -0600 | [diff] [blame] | 389 | parser.add_argument( |
| 390 | "-c", |
| 391 | "--configuration-file", |
| 392 | dest="configuration_file", |
| 393 | help="The phosphor-regulators configuration file", |
| 394 | ) |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 395 | |
| 396 | args = parser.parse_args() |
| 397 | |
| 398 | if not args.schema_file: |
| 399 | parser.print_help() |
| 400 | sys.exit("Error: Schema file is required.") |
Bob King | b7552f0 | 2020-10-15 14:34:17 +0800 | [diff] [blame] | 401 | if not os.path.exists(args.schema_file): |
| 402 | parser.print_help() |
| 403 | sys.exit("Error: Schema file does not exist.") |
| 404 | if not os.access(args.schema_file, os.R_OK): |
| 405 | parser.print_help() |
| 406 | sys.exit("Error: Schema file is not readable.") |
| 407 | if not validate_JSON_format(args.schema_file): |
| 408 | parser.print_help() |
| 409 | sys.exit("Error: Schema file is not in the JSON format.") |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 410 | if not args.configuration_file: |
| 411 | parser.print_help() |
| 412 | sys.exit("Error: Configuration file is required.") |
Bob King | b7552f0 | 2020-10-15 14:34:17 +0800 | [diff] [blame] | 413 | if not os.path.exists(args.configuration_file): |
| 414 | parser.print_help() |
| 415 | sys.exit("Error: Configuration file does not exist.") |
| 416 | if not os.access(args.configuration_file, os.R_OK): |
| 417 | parser.print_help() |
| 418 | sys.exit("Error: Configuration file is not readable.") |
| 419 | if not validate_JSON_format(args.configuration_file): |
| 420 | parser.print_help() |
| 421 | sys.exit("Error: Configuration file is not in the JSON format.") |
Bob King | 5cc0128 | 2019-12-17 18:11:57 +0800 | [diff] [blame] | 422 | |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 423 | config_json = validate_schema(args.configuration_file, args.schema_file) |
Bob King | d114cd9 | 2020-02-10 13:56:02 +0800 | [diff] [blame] | 424 | |
Bob King | 95b796a | 2020-01-15 14:45:06 +0800 | [diff] [blame] | 425 | check_for_duplicates(config_json) |
Bob King | d114cd9 | 2020-02-10 13:56:02 +0800 | [diff] [blame] | 426 | |
| 427 | check_infinite_loops(config_json) |
| 428 | |
Bob King | 23dd60b | 2020-02-26 10:23:21 +0800 | [diff] [blame] | 429 | check_run_rule_value_exists(config_json) |
Bob King | e959754 | 2020-02-26 10:47:40 +0800 | [diff] [blame] | 430 | |
| 431 | check_set_device_value_exists(config_json) |
Bob King | 9146df2 | 2020-02-26 10:49:33 +0800 | [diff] [blame] | 432 | |
| 433 | check_rule_id_exists(config_json) |
Bob King | a533d70 | 2020-02-26 10:51:24 +0800 | [diff] [blame] | 434 | |
Shawn McCarney | 5d4a9c7 | 2021-08-19 18:45:59 -0500 | [diff] [blame] | 435 | check_device_id_exists(config_json) |
| 436 | |
Bob King | a533d70 | 2020-02-26 10:51:24 +0800 | [diff] [blame] | 437 | check_number_of_elements_in_masks(config_json) |